Compare commits
29
Commits
71307f3e53
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9f617f1cc | ||
|
|
b0964dfe72 | ||
|
|
5d68961188 | ||
|
|
656ce63d55 | ||
|
|
0cd230b577 | ||
|
|
3c0e177905 | ||
|
|
bf62257884 | ||
|
|
a0beb9eac7 | ||
|
|
8db6f7b115 | ||
|
|
f847154ba2 | ||
|
|
698c1a1099 | ||
|
|
f47fde76c0 | ||
|
|
83e5f7e040 | ||
|
|
ef2e7654e2 | ||
|
|
9a0e6d7524 | ||
|
|
0f9f81d568 | ||
|
|
1f7720d54e | ||
|
|
dd72a8e3fd | ||
|
|
09eaa78ba1 | ||
|
|
936e326229 | ||
|
|
a2ff667b68 | ||
|
|
8b66098f3d | ||
|
|
2520e9589f | ||
|
|
2fe2ef5d74 | ||
|
|
8388f448f3 | ||
|
|
4db0f654ed | ||
|
|
1408c6ac83 | ||
|
|
fc851d2106 | ||
|
|
f812505a1e |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"asset":{
|
"asset":{
|
||||||
"generator":"Khronos glTF Blender I/O v4.3.47",
|
"generator":"Khronos glTF Blender I/O v5.0.21",
|
||||||
"version":"2.0"
|
"version":"2.0"
|
||||||
},
|
},
|
||||||
"extensionsUsed":[
|
"extensionsUsed":[
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
"translation":[
|
"translation":[
|
||||||
4.076245307922363,
|
4.076245307922363,
|
||||||
5.903861999511719,
|
5.903861999511719,
|
||||||
-1.0054539442062378
|
2.520627498626709
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -66,9 +66,9 @@
|
|||||||
0.8937962055206299
|
0.8937962055206299
|
||||||
],
|
],
|
||||||
"translation":[
|
"translation":[
|
||||||
4.200888156890869,
|
3.8443074226379395,
|
||||||
2.8001465797424316,
|
2.5564608573913574,
|
||||||
3.949000835418701
|
3.6128811836242676
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -88,6 +88,12 @@
|
|||||||
"type":"perspective"
|
"type":"perspective"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"materials":[
|
||||||
|
{
|
||||||
|
"doubleSided":true,
|
||||||
|
"name":"Material.002"
|
||||||
|
}
|
||||||
|
],
|
||||||
"meshes":[
|
"meshes":[
|
||||||
{
|
{
|
||||||
"name":"Suzanne",
|
"name":"Suzanne",
|
||||||
@@ -96,9 +102,11 @@
|
|||||||
"attributes":{
|
"attributes":{
|
||||||
"POSITION":0,
|
"POSITION":0,
|
||||||
"NORMAL":1,
|
"NORMAL":1,
|
||||||
"TEXCOORD_0":2
|
"TEXCOORD_0":2,
|
||||||
|
"TANGENT":3
|
||||||
},
|
},
|
||||||
"indices":3
|
"indices":4,
|
||||||
|
"material":0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -107,67 +115,79 @@
|
|||||||
{
|
{
|
||||||
"bufferView":0,
|
"bufferView":0,
|
||||||
"componentType":5126,
|
"componentType":5126,
|
||||||
"count":1966,
|
"count":3410,
|
||||||
"max":[
|
"max":[
|
||||||
1.3671875,
|
1.325934886932373,
|
||||||
0.984375,
|
0.9392362236976624,
|
||||||
0.8515625
|
0.8223199844360352
|
||||||
],
|
],
|
||||||
"min":[
|
"min":[
|
||||||
-1.3671875,
|
-1.325934886932373,
|
||||||
-0.984375,
|
-0.9704862236976624,
|
||||||
-0.8515625
|
-0.7782661318778992
|
||||||
],
|
],
|
||||||
"type":"VEC3"
|
"type":"VEC3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bufferView":1,
|
"bufferView":1,
|
||||||
"componentType":5126,
|
"componentType":5126,
|
||||||
"count":1966,
|
"count":3410,
|
||||||
"type":"VEC3"
|
"type":"VEC3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bufferView":2,
|
"bufferView":2,
|
||||||
"componentType":5126,
|
"componentType":5126,
|
||||||
"count":1966,
|
"count":3410,
|
||||||
"type":"VEC2"
|
"type":"VEC2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bufferView":3,
|
"bufferView":3,
|
||||||
|
"componentType":5126,
|
||||||
|
"count":3410,
|
||||||
|
"type":"VEC4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView":4,
|
||||||
"componentType":5123,
|
"componentType":5123,
|
||||||
"count":2904,
|
"count":11808,
|
||||||
"type":"SCALAR"
|
"type":"SCALAR"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"bufferViews":[
|
"bufferViews":[
|
||||||
{
|
{
|
||||||
"buffer":0,
|
"buffer":0,
|
||||||
"byteLength":23592,
|
"byteLength":40920,
|
||||||
"byteOffset":0,
|
"byteOffset":0,
|
||||||
"target":34962
|
"target":34962
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"buffer":0,
|
"buffer":0,
|
||||||
"byteLength":23592,
|
"byteLength":40920,
|
||||||
"byteOffset":23592,
|
"byteOffset":40920,
|
||||||
"target":34962
|
"target":34962
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"buffer":0,
|
"buffer":0,
|
||||||
"byteLength":15728,
|
"byteLength":27280,
|
||||||
"byteOffset":47184,
|
"byteOffset":81840,
|
||||||
"target":34962
|
"target":34962
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"buffer":0,
|
"buffer":0,
|
||||||
"byteLength":5808,
|
"byteLength":54560,
|
||||||
"byteOffset":62912,
|
"byteOffset":109120,
|
||||||
|
"target":34962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer":0,
|
||||||
|
"byteLength":23616,
|
||||||
|
"byteOffset":163680,
|
||||||
"target":34963
|
"target":34963
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"buffers":[
|
"buffers":[
|
||||||
{
|
{
|
||||||
"byteLength":68720,
|
"byteLength":187296,
|
||||||
"uri":"monkey.bin"
|
"uri":"monkey.bin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
add_subdirectory(console)
|
add_subdirectory(console)
|
||||||
|
add_subdirectory(shaders)
|
||||||
|
|
||||||
|
|
||||||
#################
|
#################
|
||||||
|
|||||||
@@ -11,17 +11,25 @@
|
|||||||
#include "ui/ui_main.h"
|
#include "ui/ui_main.h"
|
||||||
#include "adapter/adapter_texture.h"
|
#include "adapter/adapter_texture.h"
|
||||||
#include "device/dvc_render_target.h"
|
#include "device/dvc_render_target.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "scene/dvc_scene.h"
|
||||||
|
|
||||||
#include <scene/dvc_scene.h>
|
int32_t g_screenWidth = 2048;
|
||||||
|
int32_t g_screenHeight = 1024;
|
||||||
int32_t g_screenWidth = 1024;
|
|
||||||
int32_t g_screenHeight = 768;
|
|
||||||
static SDL_Window* window = NULL;
|
static SDL_Window* window = NULL;
|
||||||
AdapterTexture g_adapterTexture;
|
AdapterTexture g_adapterTexture;
|
||||||
SDL_GLContext gl_context;
|
SDL_GLContext gl_context;
|
||||||
davinci::RenderTarget g_renderTarget;
|
davinci::RenderTarget g_renderTarget;
|
||||||
|
davinci::AntiAliasingTech g_aaTech = davinci::AntiAliasingTech::AA_None;
|
||||||
|
|
||||||
|
int32_t g_canvasWidth = 1024;
|
||||||
|
int32_t g_canvasHeight = 512;
|
||||||
|
davinci::Device g_device;
|
||||||
davinci::Scene g_scene;
|
davinci::Scene g_scene;
|
||||||
|
int32_t g_mousePosX = 0;
|
||||||
|
int32_t g_mousePosY = 0;
|
||||||
|
davinci::fVector4 g_mouseColor = davinci::fVector4::BLACK;
|
||||||
|
int32_t g_debugMaterialID = 0;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
//int main(int argc, char* argv[])
|
//int main(int argc, char* argv[])
|
||||||
@@ -99,7 +107,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[])
|
|||||||
|
|
||||||
// init davinci
|
// init davinci
|
||||||
g_scene.init();
|
g_scene.init();
|
||||||
g_renderTarget.init(512, 256);
|
g_renderTarget.init(g_canvasWidth, g_canvasHeight);
|
||||||
g_adapterTexture.updateTexture();
|
g_adapterTexture.updateTexture();
|
||||||
|
|
||||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||||
@@ -153,9 +161,23 @@ SDL_AppResult SDL_AppIterate(void* appstate)
|
|||||||
|
|
||||||
//draw render result
|
//draw render result
|
||||||
g_adapterTexture.updateTexture(0, 0, g_renderTarget.getColorBuffer());
|
g_adapterTexture.updateTexture(0, 0, g_renderTarget.getColorBuffer());
|
||||||
g_adapterTexture.updateTexture(512, 0, g_renderTarget.getDepthBuffer());
|
g_adapterTexture.updateTexture(g_canvasWidth, 0, g_renderTarget.getDepthBuffer());
|
||||||
g_adapterTexture.draw();
|
g_adapterTexture.draw();
|
||||||
|
|
||||||
|
float mousePosX, mousePosY;
|
||||||
|
SDL_GetMouseState(&mousePosX, &mousePosY);
|
||||||
|
|
||||||
|
g_mousePosX = (int32_t)(mousePosX) % g_canvasWidth;
|
||||||
|
g_mousePosY = g_screenHeight - (int32_t)(mousePosY);
|
||||||
|
if(g_mousePosX>=0 && g_mousePosX < g_canvasWidth && g_mousePosY >=0 && g_mousePosY < g_canvasHeight)
|
||||||
|
{
|
||||||
|
g_mouseColor = g_renderTarget.getColorBuffer().getPixel(g_mousePosX, g_mousePosY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_mouseColor = davinci::fVector4::BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
//draw ui
|
//draw ui
|
||||||
drawMainUI();
|
drawMainUI();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "ui_main.h"
|
#include "ui_main.h"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3/SDL_opengl.h>
|
#include <SDL3/SDL_opengl.h>
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
@@ -7,7 +8,8 @@
|
|||||||
#include "imgui/imgui_impl_opengl3.h"
|
#include "imgui/imgui_impl_opengl3.h"
|
||||||
|
|
||||||
#include "scene/dvu_load_gltf.h"
|
#include "scene/dvu_load_gltf.h"
|
||||||
#include "pipe/dvc_render_queue.h"
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
#include "device/dvc_render_target.h"
|
#include "device/dvc_render_target.h"
|
||||||
#include "shader/dvc_shader_interface.h"
|
#include "shader/dvc_shader_interface.h"
|
||||||
#include "buffer/dvu_dump_buffer.h"
|
#include "buffer/dvu_dump_buffer.h"
|
||||||
@@ -15,12 +17,22 @@
|
|||||||
#include "scene/dvc_scene_node.h"
|
#include "scene/dvc_scene_node.h"
|
||||||
#include "scene/component/dvc_light_component.h"
|
#include "scene/component/dvc_light_component.h"
|
||||||
#include "../adapter/adapter_texture.h"
|
#include "../adapter/adapter_texture.h"
|
||||||
|
#include "standard/dvu_standard_material.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
|
||||||
SDL_Window* main_window;
|
SDL_Window* main_window;
|
||||||
|
|
||||||
|
extern davinci::Device g_device;
|
||||||
extern davinci::Scene g_scene;
|
extern davinci::Scene g_scene;
|
||||||
extern davinci::RenderTarget g_renderTarget;
|
extern davinci::RenderTarget g_renderTarget;
|
||||||
|
extern davinci::AntiAliasingTech g_aaTech;
|
||||||
|
extern int32_t g_mousePosX;
|
||||||
|
extern int32_t g_mousePosY;
|
||||||
|
extern davinci::fVector4 g_mouseColor;
|
||||||
|
extern int32_t g_debugMaterialID;
|
||||||
|
|
||||||
|
typedef std::map<std::string, davinci::MaterialPtr> DebugMaterialMap;
|
||||||
|
DebugMaterialMap g_debugMaterialMap;
|
||||||
|
|
||||||
bool initMainUI(SDL_Window* window, SDL_GLContext gl_context, const char* glsl_version)
|
bool initMainUI(SDL_Window* window, SDL_GLContext gl_context, const char* glsl_version)
|
||||||
{
|
{
|
||||||
@@ -70,10 +82,14 @@ void OpenFileDialogFileCallback(void* userdata, const char* const* filelist, int
|
|||||||
{
|
{
|
||||||
if (filelist == nullptr || *filelist == nullptr) return;
|
if (filelist == nullptr || *filelist == nullptr) return;
|
||||||
|
|
||||||
|
g_device.clear();
|
||||||
g_scene.clear();
|
g_scene.clear();
|
||||||
|
|
||||||
const char* szFileName = *filelist;
|
const char* szFileName = *filelist;
|
||||||
davinci_utils::load_scene_from_gltf(szFileName, g_scene);
|
if (!davinci_utils::load_scene_from_gltf(szFileName, g_device, g_scene))
|
||||||
|
{
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Open glf scene file error", main_window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawMainUI()
|
void drawMainUI()
|
||||||
@@ -94,26 +110,76 @@ void drawMainUI()
|
|||||||
}
|
}
|
||||||
if (ImGui::Button("Export"))
|
if (ImGui::Button("Export"))
|
||||||
{
|
{
|
||||||
davinci_utils::export_mesh_to_obj(g_scene);
|
davinci_utils::export_mesh_to_obj(g_device, g_scene);
|
||||||
}
|
}
|
||||||
|
const char* aaItem[] = { "none", "MSAA_2X2", "MSAA_4X4"};
|
||||||
|
ImGui::Combo("AntiAliasing", (int*)(&g_aaTech), aaItem, IM_ARRAYSIZE(aaItem));
|
||||||
|
|
||||||
|
const char* materialItems[] = {
|
||||||
|
"none",
|
||||||
|
"classic:phong",
|
||||||
|
"debug:solid_color",
|
||||||
|
"debug:base_color_texture",
|
||||||
|
"debug:normal_texture",
|
||||||
|
"debug:texture_coordinates_0",
|
||||||
|
"debug:geometry_normal"
|
||||||
|
};
|
||||||
|
ImGui::Combo("DebugMaterial", (int*)(&g_debugMaterialID), materialItems, IM_ARRAYSIZE(materialItems));
|
||||||
|
|
||||||
if (ImGui::Button("Render"))
|
if (ImGui::Button("Render"))
|
||||||
{
|
{
|
||||||
davinci::UniformBuffer uniformBuffer;
|
davinci::RenderPipe pipe(g_device);
|
||||||
|
|
||||||
|
davinci::UniformBuffer& uniformBuffer = pipe.getUniformBuffer();
|
||||||
uniformBuffer.updateStandardAttribute(g_scene);
|
uniformBuffer.updateStandardAttribute(g_scene);
|
||||||
|
|
||||||
//find Light node
|
//find Light node
|
||||||
|
uniformBuffer.setAttribute("ambient_light:color", davinci::fVector3(0.1f, 0.1f, 0.1f));
|
||||||
|
|
||||||
davinci::SceneNodeConstPtr lightNode = g_scene.getNodeWithComponent<davinci::LightComponent>();
|
davinci::SceneNodeConstPtr lightNode = g_scene.getNodeWithComponent<davinci::LightComponent>();
|
||||||
if (lightNode)
|
if (lightNode)
|
||||||
{
|
{
|
||||||
uniformBuffer.setAttribute("light0:position", lightNode->getWorldPosition());
|
uniformBuffer.setAttribute("light0:position", lightNode->getWorldPosition());
|
||||||
|
uniformBuffer.setAttribute("light0:color", davinci::fVector3::WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
davinci::RenderQueue queue;
|
pipe.setAntiAliasingTech(g_aaTech);
|
||||||
queue.build(g_scene);
|
|
||||||
|
if (g_debugMaterialID == 0) {
|
||||||
|
pipe.setDebugMaterial(nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugMaterialMap::iterator it = g_debugMaterialMap.find(materialItems[g_debugMaterialID]);
|
||||||
|
if(it==g_debugMaterialMap.end())
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr debugMaterial = davinci_utils::create_standard_material(&g_device, materialItems[g_debugMaterialID]);
|
||||||
|
if (debugMaterial)
|
||||||
|
{
|
||||||
|
debugMaterial->setupMaterial();
|
||||||
|
|
||||||
|
g_debugMaterialMap[materialItems[g_debugMaterialID]] = debugMaterial;
|
||||||
|
pipe.setDebugMaterial(debugMaterial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pipe.setDebugMaterial(it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
g_scene.buildRenderableQueue(pipe);
|
||||||
|
|
||||||
g_renderTarget.clear();
|
g_renderTarget.clear();
|
||||||
queue.process(uniformBuffer, g_renderTarget);
|
pipe.process(g_renderTarget);
|
||||||
|
|
||||||
|
//davinci_utils::dump_render_target("d:\\rendertarget", g_renderTarget);
|
||||||
}
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
ImVec2 mousePos = ImGui::GetMousePos();
|
||||||
|
ImGui::Text("MousePosition: %d,%d", g_mousePosX, g_mousePosY);
|
||||||
|
ImGui::Text("MouseColor: %.3f,%.3f,%.3f,%.3f", g_mouseColor.x, g_mouseColor.y, g_mouseColor.z, g_mouseColor.w);
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
|
|||||||
+43
-14
@@ -15,7 +15,7 @@ set(DV_CORE_MATH_INCLUDE_FILES
|
|||||||
include/math/dvc_matrix3.h
|
include/math/dvc_matrix3.h
|
||||||
include/math/dvc_matrix4.h
|
include/math/dvc_matrix4.h
|
||||||
include/math/dvc_math_util.h
|
include/math/dvc_math_util.h
|
||||||
include/math/dvc_fixmath.h
|
include/math/dvc_fix_point.h
|
||||||
)
|
)
|
||||||
source_group("include/math" FILES ${DV_CORE_MATH_INCLUDE_FILES})
|
source_group("include/math" FILES ${DV_CORE_MATH_INCLUDE_FILES})
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ set(DV_CORE_MATH_SOURCE_FILES
|
|||||||
source/math/dvc_matrix3.cpp
|
source/math/dvc_matrix3.cpp
|
||||||
source/math/dvc_matrix4.cpp
|
source/math/dvc_matrix4.cpp
|
||||||
source/math/dvc_math_util.cpp
|
source/math/dvc_math_util.cpp
|
||||||
|
source/math/dvc_fix_point.cpp
|
||||||
)
|
)
|
||||||
source_group("source/math" FILES ${DV_CORE_MATH_SOURCE_FILES})
|
source_group("source/math" FILES ${DV_CORE_MATH_SOURCE_FILES})
|
||||||
|
|
||||||
@@ -68,11 +69,17 @@ source_group("source/scene/component" FILES ${DV_CORE_SCENE_COMPONENT_SOURCE_FIL
|
|||||||
#################
|
#################
|
||||||
set(DV_CORE_ASSET_INCLUDE_FILES
|
set(DV_CORE_ASSET_INCLUDE_FILES
|
||||||
include/asset/dvc_mesh.h
|
include/asset/dvc_mesh.h
|
||||||
|
include/asset/dvc_image.h
|
||||||
|
include/asset/dvc_texture.h
|
||||||
|
include/asset/dvc_material.h
|
||||||
)
|
)
|
||||||
source_group("include/asset" FILES ${DV_CORE_ASSET_INCLUDE_FILES})
|
source_group("include/asset" FILES ${DV_CORE_ASSET_INCLUDE_FILES})
|
||||||
|
|
||||||
set(DV_CORE_ASSET_SOURCE_FILES
|
set(DV_CORE_ASSET_SOURCE_FILES
|
||||||
source/asset/dvc_mesh.cpp
|
source/asset/dvc_mesh.cpp
|
||||||
|
source/asset/dvc_image.cpp
|
||||||
|
source/asset/dvc_texture.cpp
|
||||||
|
source/asset/dvc_material.cpp
|
||||||
)
|
)
|
||||||
source_group("source/asset" FILES ${DV_CORE_ASSET_SOURCE_FILES})
|
source_group("source/asset" FILES ${DV_CORE_ASSET_SOURCE_FILES})
|
||||||
|
|
||||||
@@ -80,6 +87,7 @@ source_group("source/asset" FILES ${DV_CORE_ASSET_SOURCE_FILES})
|
|||||||
# device
|
# device
|
||||||
#################
|
#################
|
||||||
set(DV_CORE_DEVICE_INCLUDE_FILES
|
set(DV_CORE_DEVICE_INCLUDE_FILES
|
||||||
|
include/device/dvc_device.h
|
||||||
include/device/dvc_buffer.h
|
include/device/dvc_buffer.h
|
||||||
include/device/dvc_buffer_view.h
|
include/device/dvc_buffer_view.h
|
||||||
include/device/dvc_buffer_accessor.h
|
include/device/dvc_buffer_accessor.h
|
||||||
@@ -91,6 +99,7 @@ set(DV_CORE_DEVICE_INCLUDE_FILES
|
|||||||
source_group("include/device" FILES ${DV_CORE_DEVICE_INCLUDE_FILES})
|
source_group("include/device" FILES ${DV_CORE_DEVICE_INCLUDE_FILES})
|
||||||
|
|
||||||
set(DV_CORE_DEVICE_SOURCE_FILES
|
set(DV_CORE_DEVICE_SOURCE_FILES
|
||||||
|
source/device/dvc_device.cpp
|
||||||
source/device/dvc_buffer.cpp
|
source/device/dvc_buffer.cpp
|
||||||
source/device/dvc_buffer_view.cpp
|
source/device/dvc_buffer_view.cpp
|
||||||
source/device/dvc_buffer_accessor.cpp
|
source/device/dvc_buffer_accessor.cpp
|
||||||
@@ -105,37 +114,52 @@ source_group("source/device" FILES ${DV_CORE_DEVICE_SOURCE_FILES})
|
|||||||
# pipe
|
# pipe
|
||||||
#################
|
#################
|
||||||
set(DV_CORE_PIPE_INCLUDE_FILES
|
set(DV_CORE_PIPE_INCLUDE_FILES
|
||||||
include/pipe/dvc_render_queue.h
|
include/pipe/dvc_render_pipe.h
|
||||||
include/pipe/dvc_renderable.h
|
include/pipe/dvc_renderable.h
|
||||||
include/pipe/dvc_renderable_entity.h
|
include/pipe/dvc_renderable_entity.h
|
||||||
include/pipe/dvc_render_step_IA.h
|
include/pipe/dvc_render_step0_input_assember.h
|
||||||
include/pipe/dvc_render_step_VS.h
|
include/pipe/dvc_render_step1_vertex_shader.h
|
||||||
include/pipe/dvc_render_step_PS.h
|
include/pipe/dvc_render_step2_rasterizer.h
|
||||||
include/pipe/dvc_rasterizer.h
|
include/pipe/dvc_render_step3_output_merge.h
|
||||||
)
|
)
|
||||||
source_group("include/pipe" FILES ${DV_CORE_PIPE_INCLUDE_FILES})
|
source_group("include/pipe" FILES ${DV_CORE_PIPE_INCLUDE_FILES})
|
||||||
|
|
||||||
set(DV_CORE_PIPE_SOURCE_FILES
|
set(DV_CORE_PIPE_SOURCE_FILES
|
||||||
source/pipe/dvc_render_queue.cpp
|
source/pipe/dvc_render_pipe.cpp
|
||||||
source/pipe/dvc_renderable.cpp
|
source/pipe/dvc_renderable.cpp
|
||||||
source/pipe/dvc_renderable_entity.cpp
|
source/pipe/dvc_renderable_entity.cpp
|
||||||
source/pipe/dvc_render_step_IA.cpp
|
source/pipe/dvc_render_step0_input_assember.cpp
|
||||||
source/pipe/dvc_render_step_VS.cpp
|
source/pipe/dvc_render_step1_vertex_shader.cpp
|
||||||
source/pipe/dvc_render_step_PS.cpp
|
source/pipe/dvc_render_step2_rasterizer.cpp
|
||||||
source/pipe/dvc_rasterizer_triangle.cpp
|
source/pipe/dvc_render_step3_output_merge.cpp
|
||||||
)
|
)
|
||||||
source_group("source/pipe" FILES ${DV_CORE_PIPE_SOURCE_FILES})
|
source_group("source/pipe" FILES ${DV_CORE_PIPE_SOURCE_FILES})
|
||||||
|
|
||||||
|
#################
|
||||||
|
# rasterizer
|
||||||
|
#################
|
||||||
|
set(DV_CORE_RASTERIZER_INCLUDE_FILES
|
||||||
|
include/rasterizer/dvc_rasterizer_triangle.h
|
||||||
|
)
|
||||||
|
source_group("include/rasterizer" FILES ${DV_CORE_RASTERIZER_INCLUDE_FILES})
|
||||||
|
|
||||||
|
set(DV_CORE_RASTERIZER_SOURCE_FILES
|
||||||
|
source/rasterizer/dvc_rasterizer_triangle.cpp
|
||||||
|
)
|
||||||
|
source_group("source/rasterizer" FILES ${DV_CORE_RASTERIZER_SOURCE_FILES})
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# shader
|
# shader
|
||||||
#################
|
#################
|
||||||
set(DV_CORE_SHADER_INCLUDE_FILES
|
set(DV_CORE_SHADER_INCLUDE_FILES
|
||||||
include/shader/dvc_shader_interface.h
|
include/shader/dvc_shader_interface.h
|
||||||
|
include/shader/dvc_shader_functions.h
|
||||||
)
|
)
|
||||||
source_group("include/shader" FILES ${DV_CORE_SHADER_INCLUDE_FILES})
|
source_group("include/shader" FILES ${DV_CORE_SHADER_INCLUDE_FILES})
|
||||||
|
|
||||||
set(DV_CORE_SHADER_SOURCE_FILES
|
set(DV_CORE_SHADER_SOURCE_FILES
|
||||||
source/shader/dvc_shader_interface.cpp
|
source/shader/dvc_shader_interface.cpp
|
||||||
|
source/shader/dvc_shader_functions.cpp
|
||||||
)
|
)
|
||||||
source_group("source/shader" FILES ${DV_CORE_SHADER_SOURCE_FILES})
|
source_group("source/shader" FILES ${DV_CORE_SHADER_SOURCE_FILES})
|
||||||
|
|
||||||
@@ -161,6 +185,8 @@ add_library(dv_core SHARED
|
|||||||
${DV_CORE_ASSET_SOURCE_FILES}
|
${DV_CORE_ASSET_SOURCE_FILES}
|
||||||
${DV_CORE_PIPE_INCLUDE_FILES}
|
${DV_CORE_PIPE_INCLUDE_FILES}
|
||||||
${DV_CORE_PIPE_SOURCE_FILES}
|
${DV_CORE_PIPE_SOURCE_FILES}
|
||||||
|
${DV_CORE_RASTERIZER_INCLUDE_FILES}
|
||||||
|
${DV_CORE_RASTERIZER_SOURCE_FILES}
|
||||||
${DV_CORE_SHADER_INCLUDE_FILES}
|
${DV_CORE_SHADER_INCLUDE_FILES}
|
||||||
${DV_CORE_SHADER_SOURCE_FILES}
|
${DV_CORE_SHADER_SOURCE_FILES}
|
||||||
)
|
)
|
||||||
@@ -174,15 +200,18 @@ target_compile_definitions(dv_core
|
|||||||
#################
|
#################
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET dv_core POST_BUILD
|
TARGET dv_core POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_core> ${CMAKE_BINARY_DIR}/source/console/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>)
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_core> ${CMAKE_BINARY_DIR}/source/console/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>/$<TARGET_FILE_NAME:dv_core>
|
||||||
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET dv_core POST_BUILD
|
TARGET dv_core POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_core> ${CMAKE_BINARY_DIR}/test/unit/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>)
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_core> ${CMAKE_BINARY_DIR}/test/unit/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>/$<TARGET_FILE_NAME:dv_core>
|
||||||
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET dv_core POST_BUILD
|
TARGET dv_core POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_core> ${CMAKE_BINARY_DIR}/test/rasterization/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>)
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_core> ${CMAKE_BINARY_DIR}/test/rasterization/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>/$<TARGET_FILE_NAME:dv_core>
|
||||||
|
)
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# install
|
# install
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "dvc_pre_declare.h"
|
||||||
|
#include "math/dvc_vector2.h"
|
||||||
|
#include "math/dvc_vector4.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class DV_CORE_API Image
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int32_t getID(void) const { return m_id; }
|
||||||
|
int32_t getWidth(void) const { return m_width; }
|
||||||
|
int32_t getHeight(void) const { return m_height; }
|
||||||
|
PixelFormat getPixelFormat(void) const { return m_pixelFormat; }
|
||||||
|
DeviceBufferConstPtr getPixelBuffer(void) const { return m_pixelBuffer; }
|
||||||
|
|
||||||
|
fVector4 getPixel(int32_t u, int32_t v) const;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
bool initWithPixelData(Device& device, int32_t width, int32_t height,
|
||||||
|
PixelFormat pixelFormat, const uint8_t* data, size_t dataSize);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int32_t m_id;
|
||||||
|
int32_t m_width;
|
||||||
|
int32_t m_height;
|
||||||
|
PixelFormat m_pixelFormat;
|
||||||
|
size_t m_pixelByteSize;
|
||||||
|
DeviceBufferPtr m_pixelBuffer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Image(int32_t id);
|
||||||
|
~Image();
|
||||||
|
};
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "dvc_pre_declare.h"
|
||||||
|
#include "math/dvc_vector2.h"
|
||||||
|
#include "math/dvc_vector3.h"
|
||||||
|
#include "math/dvc_vector4.h"
|
||||||
|
#include "math/dvc_matrix3.h"
|
||||||
|
#include "math/dvc_matrix4.h"
|
||||||
|
#include "dvc_texture.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class DV_CORE_API Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::variant<int32_t, float32_t, fVector2, fVector3, fVector4, fMatrix3, fMatrix4, TextureInfo> Value;
|
||||||
|
|
||||||
|
struct Param
|
||||||
|
{
|
||||||
|
enum ParamType
|
||||||
|
{
|
||||||
|
PF_Int32,
|
||||||
|
PT_Float,
|
||||||
|
PT_Float2,
|
||||||
|
PT_Float3,
|
||||||
|
PT_Float4,
|
||||||
|
PT_Matrix3,
|
||||||
|
PT_Matrix4,
|
||||||
|
PT_Texture,
|
||||||
|
};
|
||||||
|
std::string name;
|
||||||
|
ParamType type;
|
||||||
|
Value value;
|
||||||
|
|
||||||
|
Param() = delete;
|
||||||
|
Param(int32_t v) : type(PF_Int32), value(v) { }
|
||||||
|
Param(float32_t v) : type(PT_Float), value(v) { }
|
||||||
|
Param(const fVector2& v) : type(PT_Float2), value(v) {}
|
||||||
|
Param(const fVector3& v) : type(PT_Float3), value(v) {}
|
||||||
|
Param(const fVector4& v) : type(PT_Float4), value(v) {}
|
||||||
|
Param(const fMatrix3& v) : type(PT_Matrix3), value(v) {}
|
||||||
|
Param(const fMatrix4& v) : type(PT_Matrix4), value(v) {}
|
||||||
|
Param(const TextureInfo& v) : type(PT_Texture), value(v) {}
|
||||||
|
};
|
||||||
|
typedef std::map<std::string, Param> ParamMap;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
bool setParam(const char* name, const T& value)
|
||||||
|
{
|
||||||
|
ParamMap::iterator it = m_params.find(name);
|
||||||
|
if(it==m_params.end() || (!std::holds_alternative<T>(it->second.value)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
it->second.value = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool getParam(const char* name, T& value) const
|
||||||
|
{
|
||||||
|
ParamMap::const_iterator it = m_params.find(name);
|
||||||
|
if(it==m_params.end() || (!std::holds_alternative<T>(it->second.value)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = std::get<T>(it->second.value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
int32_t getID(void) const { return m_id; }
|
||||||
|
|
||||||
|
VertexShaderInterface* getVertexShader() const {
|
||||||
|
return m_vertexShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
FragementShaderInterface* getFragementShader() const {
|
||||||
|
return m_fragementShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool setupMaterial();
|
||||||
|
virtual bool pickupParam(const davinci::MaterialConstPtr otherMaterial) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setVertexShader(const char* szShaderFile, const char* vertexShaderName);
|
||||||
|
void setFragementShader(const char* szShaderFile, const char* fragementShaderName);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool registerParam(const char* name, const T& defaultValue) {
|
||||||
|
if (m_params.find(name) != m_params.end()) return false;
|
||||||
|
m_params.insert(std::make_pair(name, Param(defaultValue)));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int32_t m_id;
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
VertexShaderInterface* m_vertexShader = nullptr;
|
||||||
|
FragementShaderInterface* m_fragementShader = nullptr;
|
||||||
|
|
||||||
|
std::string m_vertexshaderFile;
|
||||||
|
std::string m_vertexShaderName;
|
||||||
|
|
||||||
|
std::string m_fragementShaderFile;
|
||||||
|
std::string m_fragementShaderName;
|
||||||
|
|
||||||
|
ParamMap m_params;
|
||||||
|
public:
|
||||||
|
Material(int32_t id, const char* name);
|
||||||
|
~Material();
|
||||||
|
};
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -14,12 +14,15 @@ public:
|
|||||||
PrimitiveType type;
|
PrimitiveType type;
|
||||||
PrimitiveAttributes attributes;
|
PrimitiveAttributes attributes;
|
||||||
DeviceBufferAccessorConstPtr indices;
|
DeviceBufferAccessorConstPtr indices;
|
||||||
|
MaterialPtr material;
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<Primitive> PrimitivePtr;
|
typedef std::shared_ptr<Primitive> PrimitivePtr;
|
||||||
typedef std::shared_ptr<const Primitive> PrimitiveConstPtr;
|
typedef std::shared_ptr<const Primitive> PrimitiveConstPtr;
|
||||||
typedef std::vector<PrimitivePtr> PrimitiveArray;
|
typedef std::vector<PrimitivePtr> PrimitiveArray;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int32_t getID(void) const { return m_id; }
|
||||||
|
|
||||||
const std::string& getName(void) const {
|
const std::string& getName(void) const {
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
@@ -31,11 +34,12 @@ public:
|
|||||||
PrimitiveConstPtr getPrimitive(int32_t index) const;
|
PrimitiveConstPtr getPrimitive(int32_t index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int32_t m_id;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
PrimitiveArray m_primitiveArray;
|
PrimitiveArray m_primitiveArray;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Mesh(const std::string& name);
|
Mesh(int32_t id, const std::string& name);
|
||||||
~Mesh();
|
~Mesh();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "dvc_pre_declare.h"
|
||||||
|
#include "math/dvc_vector2.h"
|
||||||
|
#include "math/dvc_vector4.h"
|
||||||
|
#include "math/dvc_matrix3.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class DV_CORE_API Texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int32_t getID(void) const { return m_id; }
|
||||||
|
ImagePtr getImage(void) const { return m_image; }
|
||||||
|
|
||||||
|
void setImage(const ImagePtr& image) { m_image = image; }
|
||||||
|
|
||||||
|
fVector4 sample(const fVector2& uv) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t m_id;
|
||||||
|
ImagePtr m_image;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Texture(int32_t id);
|
||||||
|
~Texture();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextureInfo
|
||||||
|
{
|
||||||
|
TextureConstPtr texture;
|
||||||
|
int32_t texCoord = 0;
|
||||||
|
fMatrix3 uvTransform;
|
||||||
|
};
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -10,6 +10,7 @@ public:
|
|||||||
void init(size_t _length);
|
void init(size_t _length);
|
||||||
void clear(void);
|
void clear(void);
|
||||||
|
|
||||||
|
int32_t getID(void) const { return m_id; }
|
||||||
size_t length(void) const { return m_length; }
|
size_t length(void) const { return m_length; }
|
||||||
|
|
||||||
const uint8_t* ptr(size_t offseet) const {
|
const uint8_t* ptr(size_t offseet) const {
|
||||||
@@ -20,12 +21,12 @@ public:
|
|||||||
return m_ptr + offseet;
|
return m_ptr + offseet;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
int32_t m_id;
|
||||||
uint8_t* m_ptr;
|
uint8_t* m_ptr;
|
||||||
size_t m_length;
|
size_t m_length;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DeviceBuffer();
|
DeviceBuffer(int32_t id, size_t _length);
|
||||||
DeviceBuffer(size_t _length);
|
|
||||||
~DeviceBuffer();
|
~DeviceBuffer();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ DV_CORE_BEGIN_NAMESPACE
|
|||||||
class DV_CORE_API DeviceBufferAccessor
|
class DV_CORE_API DeviceBufferAccessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
int32_t getID(void) const { return m_id; }
|
||||||
|
|
||||||
const DeviceBufferViewConstPtr getBufferView(void) const {
|
const DeviceBufferViewConstPtr getBufferView(void) const {
|
||||||
return m_bufferView;
|
return m_bufferView;
|
||||||
}
|
}
|
||||||
@@ -39,6 +41,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int32_t m_id;
|
||||||
DeviceBufferViewConstPtr m_bufferView;
|
DeviceBufferViewConstPtr m_bufferView;
|
||||||
size_t m_offset;
|
size_t m_offset;
|
||||||
size_t m_count;
|
size_t m_count;
|
||||||
@@ -48,7 +51,7 @@ private:
|
|||||||
size_t m_elementSize;
|
size_t m_elementSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DeviceBufferAccessor(DeviceBufferViewConstPtr bufferView, size_t offset, size_t count, ComponentType componentType, DataType dataType);
|
DeviceBufferAccessor(int32_t id, DeviceBufferViewConstPtr bufferView, size_t offset, size_t count, ComponentType componentType, DataType dataType);
|
||||||
~DeviceBufferAccessor();
|
~DeviceBufferAccessor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ DV_CORE_BEGIN_NAMESPACE
|
|||||||
class DV_CORE_API DeviceBufferView
|
class DV_CORE_API DeviceBufferView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
int32_t getID(void) const { return m_id; }
|
||||||
|
|
||||||
const DeviceBufferConstPtr getBuffer(void) const {
|
const DeviceBufferConstPtr getBuffer(void) const {
|
||||||
return m_buffer;
|
return m_buffer;
|
||||||
}
|
}
|
||||||
@@ -25,13 +27,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int32_t m_id;
|
||||||
DeviceBufferConstPtr m_buffer;
|
DeviceBufferConstPtr m_buffer;
|
||||||
size_t m_offset;
|
size_t m_offset;
|
||||||
size_t m_length;
|
size_t m_length;
|
||||||
size_t m_stride;
|
size_t m_stride;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DeviceBufferView(DeviceBufferConstPtr buffer, size_t offset, size_t length, size_t stride);
|
DeviceBufferView(int32_t id, DeviceBufferConstPtr buffer, size_t offset, size_t length, size_t stride);
|
||||||
~DeviceBufferView();
|
~DeviceBufferView();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "dvc_pre_declare.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class DV_CORE_API Device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
public:
|
||||||
|
DeviceBufferPtr newDeviceBuffer(size_t length);
|
||||||
|
DeviceBufferConstPtr getDeviceBuffer(int32_t id) const;
|
||||||
|
|
||||||
|
DeviceBufferViewPtr newDeviceBufferView(DeviceBufferConstPtr buffer, size_t offset, size_t length, size_t stride);
|
||||||
|
DeviceBufferViewPtr getDeviceBufferView(int32_t id) const;
|
||||||
|
|
||||||
|
DeviceBufferAccessorPtr newDeviceBufferAccessor(DeviceBufferViewConstPtr bufferView, size_t offset,
|
||||||
|
size_t count, ComponentType componentType, DataType dataType);
|
||||||
|
DeviceBufferAccessorPtr getDeviceBufferAccessor(int32_t id) const;
|
||||||
|
|
||||||
|
MeshPtr newMeshAsset(const std::string& name);
|
||||||
|
MeshPtr getMesh(int32_t id) const;
|
||||||
|
|
||||||
|
ImagePtr newImageAsset();
|
||||||
|
ImagePtr getImage(int32_t id) const;
|
||||||
|
|
||||||
|
TexturePtr newTextureAsset();
|
||||||
|
TexturePtr getTexture(int32_t id) const;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
MaterialPtr newMaterialAsset(const char* name) {
|
||||||
|
MaterialPtr materialPtr = std::make_shared<T>(nextID(), name);
|
||||||
|
m_materialAssetMap.insert(std::make_pair(materialPtr->getID(), materialPtr));
|
||||||
|
return materialPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialPtr getMaterial(int32_t id) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t nextID() {
|
||||||
|
if (++m_currentID < 0) m_currentID = 0;
|
||||||
|
return m_currentID;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int32_t m_currentID = 0;
|
||||||
|
|
||||||
|
//device buffer
|
||||||
|
std::map<int32_t, DeviceBufferPtr> m_deviceBufferMap;
|
||||||
|
|
||||||
|
//device buffer view
|
||||||
|
std::map<int32_t, DeviceBufferViewPtr> m_bufferViewMap;
|
||||||
|
|
||||||
|
//device buffer accessor
|
||||||
|
std::map<int32_t, DeviceBufferAccessorPtr> m_bufferAccessorMap;
|
||||||
|
|
||||||
|
//mesh asset resources
|
||||||
|
std::map<int32_t, MeshPtr> m_meshAssetMap;
|
||||||
|
|
||||||
|
//image asset resources
|
||||||
|
std::map<int32_t, ImagePtr> m_imageAssetMap;
|
||||||
|
|
||||||
|
//texture asset resources
|
||||||
|
std::map<int32_t, TexturePtr> m_textureAssetMap;
|
||||||
|
|
||||||
|
//material asset resources
|
||||||
|
std::map<int32_t, MaterialPtr> m_materialAssetMap;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Device();
|
||||||
|
~Device();
|
||||||
|
};
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -22,9 +22,9 @@ public:
|
|||||||
bool addElement(const std::string& name, VertexElementType elementType,
|
bool addElement(const std::string& name, VertexElementType elementType,
|
||||||
ComponentType componentType, DataType dataType);
|
ComponentType componentType, DataType dataType);
|
||||||
|
|
||||||
const Element* getElement(size_t index) const;
|
const Element* getElementByIndex(size_t index) const;
|
||||||
const Element* getElement(VertexElementType elementType) const;
|
const Element* getElementByType(VertexElementType elementType) const;
|
||||||
const Element* getElement(const std::string& name) const;
|
const Element* getElementByName(const std::string& name) const;
|
||||||
|
|
||||||
//total byte size of each vertex
|
//total byte size of each vertex
|
||||||
size_t vertexByteSize(void) const { return m_vertexSize; }
|
size_t vertexByteSize(void) const { return m_vertexSize; }
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ enum VertexElementType
|
|||||||
{
|
{
|
||||||
VET_UNKNOWN,
|
VET_UNKNOWN,
|
||||||
|
|
||||||
VET_POSITION,
|
VET_POSITION_MODEL, VET_POSITION_WORLD, VET_POSITION_VIEW, VET_POSITION_NDC,
|
||||||
|
|
||||||
VET_NORMAL,
|
VET_NORMAL,
|
||||||
VET_TANGENT,
|
VET_TANGENT,
|
||||||
VET_BINORMAL,
|
VET_BINORMAL,
|
||||||
@@ -89,17 +90,27 @@ enum PrimitiveType
|
|||||||
|
|
||||||
enum PixelFormat
|
enum PixelFormat
|
||||||
{
|
{
|
||||||
//96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue
|
PF_UNKNOWN,
|
||||||
PF_FLOAT32_RGB,
|
|
||||||
|
|
||||||
/// 128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, 32 bits (float) for alpha
|
PF_UINT8_ALPHA,
|
||||||
PF_FLOAT32_RGBA,
|
PF_UINT8_RGB,
|
||||||
|
|
||||||
// 32-bit pixel format, 32 bits (float) for red
|
|
||||||
PF_FLOAT32_R,
|
|
||||||
|
|
||||||
/// 132-bit pixel format, 8 bits (float) for red, 8 bits (float) for green, 8 bits (float) for blue, 8 bits (float) for alpha
|
|
||||||
PF_UINT8_RGBA,
|
PF_UINT8_RGBA,
|
||||||
|
|
||||||
|
PF_UINT16_ALPHA,
|
||||||
|
PF_UINT16_RGB,
|
||||||
|
PF_UINT16_RGBA,
|
||||||
|
|
||||||
|
PF_FLOAT32_ALPHA,
|
||||||
|
PF_FLOAT32_RGB,
|
||||||
|
PF_FLOAT32_RGBA,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AntiAliasingTech
|
||||||
|
{
|
||||||
|
AA_None,
|
||||||
|
|
||||||
|
AA_MSAA_2X2,
|
||||||
|
AA_MSAA_4X4,
|
||||||
};
|
};
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
DV_CORE_END_NAMESPACE
|
||||||
|
|||||||
@@ -36,8 +36,22 @@ class Mesh;
|
|||||||
typedef std::shared_ptr<Mesh> MeshPtr;
|
typedef std::shared_ptr<Mesh> MeshPtr;
|
||||||
typedef std::shared_ptr<const Mesh> MeshConstPtr;
|
typedef std::shared_ptr<const Mesh> MeshConstPtr;
|
||||||
|
|
||||||
|
class Image;
|
||||||
|
typedef std::shared_ptr<Image> ImagePtr;
|
||||||
|
typedef std::shared_ptr<const Image> ImageConstPtr;
|
||||||
|
|
||||||
|
class Texture;
|
||||||
|
typedef std::shared_ptr<Texture> TexturePtr;
|
||||||
|
typedef std::shared_ptr<const Texture> TextureConstPtr;
|
||||||
|
|
||||||
|
class Material;
|
||||||
|
typedef std::shared_ptr<Material> MaterialPtr;
|
||||||
|
typedef std::shared_ptr<const Material> MaterialConstPtr;
|
||||||
|
|
||||||
class Scene;
|
class Scene;
|
||||||
|
|
||||||
|
class Device;
|
||||||
|
|
||||||
class SceneNode;
|
class SceneNode;
|
||||||
typedef std::shared_ptr<SceneNode> SceneNodePtr;
|
typedef std::shared_ptr<SceneNode> SceneNodePtr;
|
||||||
typedef std::shared_ptr<const SceneNode> SceneNodeConstPtr;
|
typedef std::shared_ptr<const SceneNode> SceneNodeConstPtr;
|
||||||
@@ -60,13 +74,15 @@ class LightComponent;
|
|||||||
typedef std::shared_ptr<LightComponent> LightComponentPtr;
|
typedef std::shared_ptr<LightComponent> LightComponentPtr;
|
||||||
typedef std::shared_ptr<const LightComponent> LightComponentConstPtr;
|
typedef std::shared_ptr<const LightComponent> LightComponentConstPtr;
|
||||||
|
|
||||||
class RenderQueue;
|
class RenderPipe;
|
||||||
|
|
||||||
class Renderable;
|
class Renderable;
|
||||||
typedef std::shared_ptr<Renderable> RenderablePtr;
|
typedef std::shared_ptr<Renderable> RenderablePtr;
|
||||||
typedef std::shared_ptr<const Renderable> RenderableConstPtr;
|
typedef std::shared_ptr<const Renderable> RenderableConstPtr;
|
||||||
|
typedef std::vector<RenderableConstPtr> RenderableArray;
|
||||||
|
|
||||||
class VertexShaderInterface;
|
class VertexShaderInterface;
|
||||||
|
class FragementShaderInterface;
|
||||||
|
|
||||||
class UniformBuffer;
|
class UniformBuffer;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,448 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class ifloat32
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr int32_t kShift = 16;
|
||||||
|
static constexpr float32_t kFloatScale = static_cast<float32_t>(1<<kShift); //65536.0
|
||||||
|
static constexpr float32_t kFloatInvScale = 1.f / kFloatScale;
|
||||||
|
|
||||||
|
static constexpr int32_t kZero_s1516 = 0;
|
||||||
|
static constexpr int32_t kOne_s1516 = 1 << kShift;
|
||||||
|
static constexpr int32_t kTwo_s1516 = 2 << kShift;
|
||||||
|
static constexpr int32_t kThree_s1516 = 3 << kShift;
|
||||||
|
static constexpr int32_t kFour_s1516 = 4 << kShift;
|
||||||
|
static constexpr int32_t kHalf_s1516 = kOne_s1516 >> 1;
|
||||||
|
static constexpr int32_t kPI_s1516 = 0x3243f;//(int32_t)(M_PI * kFloatScale);
|
||||||
|
static constexpr int32_t kPi2_s1516 = 0x6487e;
|
||||||
|
static constexpr int32_t kPiHalf_s1516 = 0x1921f;
|
||||||
|
static constexpr int32_t kE_s1516 = 0x2b7e1;
|
||||||
|
|
||||||
|
static constexpr int32_t kNegOne_s1516 = -1 << kShift;
|
||||||
|
|
||||||
|
static constexpr int32_t kMax_s1516 = 0x7fffff80; //(int32_t)(nextafter(INT32_MAX/kFloatScale, 0.f)*kFloatScale);
|
||||||
|
static constexpr int32_t kMax_int32 = kMax_s1516 >> kShift;
|
||||||
|
static constexpr float32_t kMax_float = (float32_t)kMax_s1516 * kFloatInvScale;
|
||||||
|
|
||||||
|
static constexpr int32_t kMin_s1516 = 0x80000000; // (int32_t)(nextafter(-INT32_MAX / ifloat32::kFloatScale, -FLT_MAX) * ifloat32::kFloatScale)
|
||||||
|
static constexpr int32_t kMin_int32 = kMin_s1516 >> kShift;
|
||||||
|
static constexpr float32_t kMin_float = (float32_t)kMin_s1516 * kFloatInvScale;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ifloat32() : s1516(0) {}
|
||||||
|
ifloat32(const ifloat32& other) : s1516(other.s1516) {}
|
||||||
|
|
||||||
|
//Converts a float to a fixed-point value.
|
||||||
|
ifloat32(float32_t f) {
|
||||||
|
s1516 = static_cast<int32_t>(f * kFloatScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Converts a double to a fixed-point value.
|
||||||
|
ifloat32(float64_t f) {
|
||||||
|
s1516 = static_cast<int32_t>(f * kFloatScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Converts an integer to a fixed-point value.
|
||||||
|
ifloat32(int32_t n) {
|
||||||
|
s1516 = static_cast<int32_t>(n << kShift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Converts into a float.
|
||||||
|
float32_t to_float() const {
|
||||||
|
return static_cast<float32_t>(s1516 * kFloatInvScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Converts a fixed-point value into an integer by rounding it down to nearest integer. example: 3.94 -> 3, -2.1 -> -3
|
||||||
|
int32_t to_int32() const {
|
||||||
|
return static_cast<int32_t>(s1516 >> kShift);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ifloat32 from_raw(int32_t raw) {
|
||||||
|
ifloat32 ret;
|
||||||
|
ret.s1516 = raw;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
inline ifloat32& operator = (const ifloat32& other) {
|
||||||
|
s1516 = other.s1516;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator == (const ifloat32& other) const {
|
||||||
|
return (s1516 == other.s1516);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const ifloat32& other) const {
|
||||||
|
return (s1516 != other.s1516);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator < (const ifloat32& other) const {
|
||||||
|
return (s1516 < other.s1516);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator > (const ifloat32& other) const {
|
||||||
|
return (s1516 > other.s1516);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline ifloat32& operator += (const ifloat32 other) {
|
||||||
|
s1516 += other.s1516;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ifloat32& operator -= (const ifloat32 other) {
|
||||||
|
s1516 -= other.s1516;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Adds the two FP numbers together.
|
||||||
|
inline friend ifloat32 operator + (const ifloat32& l, const ifloat32& r) {
|
||||||
|
int64_t t = static_cast<int64_t>(l.s1516) + static_cast<int64_t>(r.s1516);
|
||||||
|
return from_raw(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Subtracts the two FP numbers from each other.
|
||||||
|
inline friend ifloat32 operator - (const ifloat32& l, const ifloat32& r) {
|
||||||
|
int64_t t = static_cast<int64_t>(l.s1516) - static_cast<int64_t>(r.s1516);
|
||||||
|
return from_raw(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline friend ifloat32 operator * (const ifloat32& a, const float32_t& b) {
|
||||||
|
int64_t t = static_cast<int64_t>(a.s1516) * static_cast<int64_t>(b * kFloatScale);
|
||||||
|
return from_raw(t >> kShift);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline friend ifloat32 operator * (const ifloat32& a, const int32_t& b) {
|
||||||
|
return from_raw(a.s1516 * b);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Multiplies two FP values together.
|
||||||
|
inline friend ifloat32 operator * (const ifloat32& a, const ifloat32& b) {
|
||||||
|
int64_t t = static_cast<int64_t>(a.s1516) * static_cast<int64_t>(b.s1516);
|
||||||
|
return from_raw(static_cast<int32_t>(t >> kShift));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline friend ifloat32 operator / (const ifloat32& a, const ifloat32& b) {
|
||||||
|
// pre-multiply by the base
|
||||||
|
int64_t t = static_cast<int64_t>(a.s1516) << kShift;
|
||||||
|
return from_raw(static_cast<int32_t>(t/ b.s1516));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
int32_t s1516;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ifloat64
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr int32_t kShift = 32;
|
||||||
|
static constexpr float32_t kFloatScale = static_cast<float32_t>(INT64_C(1) << kShift); //4294967296.0
|
||||||
|
static constexpr float32_t kFloatInvScale = 1.0f / kFloatScale;
|
||||||
|
static constexpr int64_t kFractionMask = (INT64_C(1) << kShift) - 1; // Space before INT64_C(1) needed because of hacky C++ code generator
|
||||||
|
|
||||||
|
//static_cast<int64_t>(nextafter(INT64_MAX / iFloat64::kFloatScale, 0.0) * iFloat64::kFloatScale);
|
||||||
|
static constexpr int64_t kMax_s3132 = INT64_C(0x7ffffffffffffc00);
|
||||||
|
static constexpr int32_t kMax_int32 = static_cast<int32_t>(kMax_s3132 >> kShift);
|
||||||
|
static constexpr float32_t kMax_float = 2.14748352e+09f; //nextafter(static_cast<float32_t>(kS3132_Max * kFloatInvScale), 0.0f);
|
||||||
|
|
||||||
|
//(int32_t)(nextafter(-INT64_MAX / iFloat64::kFloatScale, -DBL_MAX) * iFloat64::kFloatScale);
|
||||||
|
static constexpr int64_t kMin_s3132 = INT64_C(0x8000000000000000);
|
||||||
|
static constexpr int32_t kMin_int32 = static_cast<int32_t>(kMin_s3132 >> kShift);
|
||||||
|
static constexpr float32_t kMin_float = static_cast<float64_t>(kMin_s3132 * kFloatInvScale);
|
||||||
|
|
||||||
|
// special value
|
||||||
|
static DV_CORE_API const ifloat64 kMax;
|
||||||
|
static DV_CORE_API const ifloat64 kMin;
|
||||||
|
static DV_CORE_API const ifloat64 kZero; //0.0
|
||||||
|
static DV_CORE_API const ifloat64 kOne; //1.0
|
||||||
|
static DV_CORE_API const ifloat64 kTwo; //2.0
|
||||||
|
static DV_CORE_API const ifloat64 kThree; //3.0
|
||||||
|
static DV_CORE_API const ifloat64 kFour; //4.0
|
||||||
|
static DV_CORE_API const ifloat64 kHalf; //0.5
|
||||||
|
static DV_CORE_API const ifloat64 kQuater; //0.25
|
||||||
|
static DV_CORE_API const ifloat64 kOneEighth; //0.125
|
||||||
|
static DV_CORE_API const ifloat64 kPi; //3.14159265358979323846
|
||||||
|
static DV_CORE_API const ifloat64 kPi2; //6.2831853071795
|
||||||
|
static DV_CORE_API const ifloat64 kPiHalf; //1.57079632679489661923
|
||||||
|
static DV_CORE_API const ifloat64 kE; //2.71828182845904523536
|
||||||
|
static DV_CORE_API const ifloat64 kNegOne; // -1.0
|
||||||
|
|
||||||
|
public:
|
||||||
|
ifloat64() : s3132(0) {}
|
||||||
|
ifloat64(const ifloat64& other) : s3132(other.s3132) {}
|
||||||
|
|
||||||
|
//Converts a float to a fixed-point value.
|
||||||
|
ifloat64(float32_t f) {
|
||||||
|
s3132 = static_cast<int64_t>(std::round(f * kFloatScale));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Converts a double to a fixed-point value.
|
||||||
|
ifloat64(float64_t f) {
|
||||||
|
s3132 = static_cast<int64_t>(std::round(f * kFloatScale));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Converts an integer to a fixed-point value.
|
||||||
|
ifloat64(int32_t n) {
|
||||||
|
s3132 = static_cast<int64_t>(n) << kShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ifloat64(int64_t _s3132) {
|
||||||
|
s3132 = _s3132;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Converts into a float.
|
||||||
|
float32_t to_float() const {
|
||||||
|
return static_cast<float32_t>(s3132 * kFloatInvScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Converts a fixed-point value into an integer by rounding it down to nearest integer. example: 3.94 -> 3, -2.1 -> -3
|
||||||
|
int32_t to_int32() const {
|
||||||
|
return static_cast<int32_t>(s3132 >> kShift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline const ifloat64& operator + () const {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ifloat64 operator - () const {
|
||||||
|
return ifloat64(-s3132);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ifloat64& operator = (const ifloat64& other) {
|
||||||
|
s3132 = other.s3132;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator == (const ifloat64& other) const {
|
||||||
|
return (s3132 == other.s3132);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const ifloat64& other) const {
|
||||||
|
return (s3132 != other.s3132);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator < (const ifloat64& other) const {
|
||||||
|
return (s3132 < other.s3132);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator > (const ifloat64& other) const {
|
||||||
|
return (s3132 > other.s3132);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline ifloat64& operator += (const ifloat64 other) {
|
||||||
|
s3132 += other.s3132;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ifloat64& operator -= (const ifloat64 other) {
|
||||||
|
s3132 -= other.s3132;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Adds the two FP numbers together.
|
||||||
|
inline friend ifloat64 operator + (const ifloat64& a, const ifloat64& b) {
|
||||||
|
ifloat64 ret;
|
||||||
|
ret.s3132 = a.s3132 + b.s3132;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Subtracts the two FP numbers from each other.
|
||||||
|
inline friend ifloat64 operator - (const ifloat64& a, const ifloat64& b) {
|
||||||
|
ifloat64 ret;
|
||||||
|
ret.s3132 = a.s3132 - b.s3132;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline friend ifloat64 operator * (const ifloat64& a, const int32_t& b) {
|
||||||
|
ifloat64 ret;
|
||||||
|
ret.s3132 = a.s3132 * b;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline friend ifloat64 operator * (const ifloat64& a, const float32_t& b) {
|
||||||
|
ifloat64 ret;
|
||||||
|
ret.s3132 = _safeMulti(a.s3132, static_cast<int64_t>(b * kFloatScale));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Multiplies two FP values together.
|
||||||
|
inline friend ifloat64 operator * (const ifloat64& a, const ifloat64& b) {
|
||||||
|
ifloat64 ret;
|
||||||
|
ret.s3132 = _safeMulti(a.s3132, b.s3132);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline friend ifloat64 operator / (const ifloat64& a, const ifloat64& b) {
|
||||||
|
// From http://www.hackersdelight.org/hdcodetxt/divlu.c.txt
|
||||||
|
|
||||||
|
int64_t sign_dif = a.s3132 ^ b.s3132;
|
||||||
|
|
||||||
|
static const uint64_t B = INT64_C(0x100000000); // Number base (32 bits)
|
||||||
|
|
||||||
|
uint64_t abs_a = (uint64_t)((a.s3132 < 0) ? -a.s3132 : a.s3132);
|
||||||
|
uint64_t u1 = abs_a >> 32;
|
||||||
|
uint64_t u0 = abs_a << 32;
|
||||||
|
uint64_t v = (uint64_t)((b.s3132 < 0) ? -b.s3132 : b.s3132);
|
||||||
|
|
||||||
|
// Overflow?
|
||||||
|
if (u1 >= v)
|
||||||
|
{
|
||||||
|
//invalid number
|
||||||
|
ifloat64 ret;
|
||||||
|
ret.s3132 = 0x7fffffffffffffff;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift amount for norm
|
||||||
|
int32_t s = _nlz(v); // 0 <= s <= 63
|
||||||
|
v = v << s; // Normalize the divisor
|
||||||
|
uint64_t vn1 = v >> 32; // Break the divisor into two 32-bit digits
|
||||||
|
uint64_t vn0 = v & INT64_C(0xffffffff);
|
||||||
|
|
||||||
|
uint64_t un32 = (u1 << s) | (u0 >> (64 - s)) & (uint64_t)((int64_t)-s >> 63);
|
||||||
|
uint64_t un10 = u0 << s; // Shift dividend left
|
||||||
|
|
||||||
|
uint64_t un1 = un10 >> 32; // Break the right half of dividend into two digits
|
||||||
|
uint64_t un0 = un10 & INT64_C(0xffffffff);
|
||||||
|
|
||||||
|
// Compute the first quotient digit, q1
|
||||||
|
uint64_t q1 = un32 / vn1;
|
||||||
|
uint64_t rhat = un32 - q1 * vn1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((q1 >= B) || ((q1 * vn0) > (B * rhat + un1)))
|
||||||
|
{
|
||||||
|
q1 = q1 - 1;
|
||||||
|
rhat = rhat + vn1;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
} while (rhat < B);
|
||||||
|
|
||||||
|
uint64_t un21 = un32 * B + un1 - q1 * v; // Multiply and subtract
|
||||||
|
|
||||||
|
// Compute the second quotient digit, q0
|
||||||
|
uint64_t q0 = un21 / vn1;
|
||||||
|
rhat = un21 - q0 * vn1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((q0 >= B) || ((q0 * vn0) > (B * rhat + un0)))
|
||||||
|
{
|
||||||
|
q0 = q0 - 1;
|
||||||
|
rhat = rhat + vn1;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
} while (rhat < B);
|
||||||
|
|
||||||
|
// Calculate the remainder
|
||||||
|
// uint64_t r = (un21 * b + un0 - q0 * v) >> s;
|
||||||
|
// rem = (int64_t)r;
|
||||||
|
|
||||||
|
int64_t t = q1 * B + q0;
|
||||||
|
|
||||||
|
ifloat64 ret;
|
||||||
|
ret.s3132 = (sign_dif < 0) ? -(int64_t)t : (int64_t)t;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static int64_t _safeMulti(const int64_t a, const int64_t b) {
|
||||||
|
int64_t sign_diff = a ^ b;
|
||||||
|
uint64_t abs_a = a < 0 ? -a : a;
|
||||||
|
uint64_t abs_b = b < 0 ? -b : b;
|
||||||
|
|
||||||
|
uint64_t ai = abs_a >> kShift;
|
||||||
|
uint64_t af = (abs_a & kFractionMask);
|
||||||
|
uint64_t bi = abs_b >> kShift;
|
||||||
|
uint64_t bf = (abs_b & kFractionMask);
|
||||||
|
|
||||||
|
// (Ai+Af)*(Bi+Bf)=Af*Bf + Ai*(Bi+Bf) + Af*Bi
|
||||||
|
int64_t t = ((af * bf) >> kShift) + ai * abs_b + af * bi;
|
||||||
|
return (sign_diff < 0) ? -t : t;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t _nlz(uint64_t x)
|
||||||
|
{
|
||||||
|
int32_t n = 0;
|
||||||
|
if (x <= INT64_C(0x00000000FFFFFFFF)) { n = n + 32; x = x << 32; }
|
||||||
|
if (x <= INT64_C(0x0000FFFFFFFFFFFF)) { n = n + 16; x = x << 16; }
|
||||||
|
if (x <= INT64_C(0x00FFFFFFFFFFFFFF)) { n = n + 8; x = x << 8; }
|
||||||
|
if (x <= INT64_C(0x0FFFFFFFFFFFFFFF)) { n = n + 4; x = x << 4; }
|
||||||
|
if (x <= INT64_C(0x3FFFFFFFFFFFFFFF)) { n = n + 2; x = x << 2; }
|
||||||
|
if (x <= INT64_C(0x7FFFFFFFFFFFFFFF)) { n = n + 1; }
|
||||||
|
if (x == 0) return 64;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
int64_t s3132;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef ifloat32 iFloat32;
|
||||||
|
typedef ifloat64 iFloat64;
|
||||||
|
|
||||||
|
typedef ifloat64 iFloat;
|
||||||
|
|
||||||
|
struct iFloat2
|
||||||
|
{
|
||||||
|
iFloat x, y;
|
||||||
|
|
||||||
|
iFloat2() : x(0), y(0) {}
|
||||||
|
iFloat2(const iFloat2& other) : x(other.x), y(other.y) {}
|
||||||
|
iFloat2(float32_t _x, float32_t _y) : x(_x), y(_y) {}
|
||||||
|
iFloat2(iFloat _x, iFloat _y) : x(_x), y(_y) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iFloat3
|
||||||
|
{
|
||||||
|
iFloat x, y, z;
|
||||||
|
|
||||||
|
inline void add(const iFloat3& other) {
|
||||||
|
x += other.x;
|
||||||
|
y += other.y;
|
||||||
|
z += other.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sub(const iFloat3& other) {
|
||||||
|
x -= other.x;
|
||||||
|
y -= other.y;
|
||||||
|
z -= other.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void mul(const iFloat& multiplier) {
|
||||||
|
x = x * multiplier;
|
||||||
|
y = y * multiplier;
|
||||||
|
z = z * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void mul(const int32_t& multiplier) {
|
||||||
|
x = x * multiplier;
|
||||||
|
y = y * multiplier;
|
||||||
|
z = z * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline iFloat operator [] (const size_t i) const {
|
||||||
|
return *(&x + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline iFloat& operator [] (const size_t i) {
|
||||||
|
return *(&x + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
iFloat3() : x(0), y(0), z(0) {}
|
||||||
|
iFloat3(const iFloat3& other) : x(other.x), y(other.y), z(other.z) {}
|
||||||
|
iFloat3(float32_t _x, float32_t _y, float32_t _z) : x(_x), y(_y), z(_z) {}
|
||||||
|
iFloat3(iFloat _x, iFloat _y, iFloat _z) : x(_x), y(_y), z(_z) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "dvc_config.h"
|
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
typedef int64_t ifloat_t;
|
|
||||||
//typedef int64_t ifloat2_t[2];
|
|
||||||
//typedef int64_t ifloat3_t[3];
|
|
||||||
|
|
||||||
#define IFLOAT_SHIFT (16)
|
|
||||||
#define IFLOAT_SCALE ((float64_t)(1<<IFLOAT_SHIFT))
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
inline ifloat_t ifloat_init(float32_t a)
|
|
||||||
{
|
|
||||||
return (ifloat_t)((float64_t)a * IFLOAT_SCALE + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
inline ifloat_t ifloat_init(int32_t a)
|
|
||||||
{
|
|
||||||
return (int64_t)(a)<< IFLOAT_SHIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
inline float32_t ifloat_get_float(ifloat_t a)
|
|
||||||
{
|
|
||||||
return (float32_t)((float64_t)a/ IFLOAT_SCALE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
inline ifloat_t ifloat_multiply(ifloat_t a, ifloat_t b)
|
|
||||||
{
|
|
||||||
return (ifloat_t)((a * b) >> IFLOAT_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
//inline void ifloat3_add(ifloat3_t& a, const ifloat3_t& b)
|
|
||||||
//{
|
|
||||||
// a[0] += b[0]; a[1] += b[1]; a[2] += b[2];
|
|
||||||
//}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
//inline void ifloat3_sub(ifloat3_t& a, const ifloat3_t& b)
|
|
||||||
//{
|
|
||||||
// a[0] -= b[0]; a[1] -= b[1]; a[2] -= b[2];
|
|
||||||
//}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
//inline void ifloat3_cpy(ifloat3_t& a, const ifloat3_t& b)
|
|
||||||
//{
|
|
||||||
// a[0] = b[0]; a[1] = b[1]; a[2] = b[2];
|
|
||||||
//}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
struct ifloat2_t
|
|
||||||
{
|
|
||||||
ifloat_t x, y;
|
|
||||||
|
|
||||||
ifloat2_t() : x(0ll), y(0ll) {}
|
|
||||||
ifloat2_t(const ifloat2_t& other) : x(other.x), y(other.y) {}
|
|
||||||
ifloat2_t(float32_t _x, float32_t _y) : x(ifloat_init(_x)), y(ifloat_init(_y)) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ifloat3_t
|
|
||||||
{
|
|
||||||
ifloat_t x, y, z;
|
|
||||||
|
|
||||||
inline void add(const ifloat3_t& other) {
|
|
||||||
x += other.x;
|
|
||||||
y += other.y;
|
|
||||||
z += other.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void sub(const ifloat3_t& other) {
|
|
||||||
x -= other.x;
|
|
||||||
y -= other.y;
|
|
||||||
z -= other.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ifloat_t operator [] (const size_t i) const {
|
|
||||||
return *(&x + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ifloat_t& operator [] (const size_t i) {
|
|
||||||
return *(&x + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
ifloat3_t() : x(0ll), y(0ll), z(0ll) {}
|
|
||||||
ifloat3_t(const ifloat3_t& other) : x(other.x), y(other.y), z(other.z) {}
|
|
||||||
ifloat3_t(float32_t _x, float32_t _y, float32_t _z) : x(ifloat_init(_x)), y(ifloat_init(_y)), z(ifloat_init(_z)) {}
|
|
||||||
ifloat3_t(ifloat_t _x, ifloat_t _y, ifloat_t _z) : x(_x), y(_y), z(_z) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
|
||||||
|
|
||||||
@@ -8,8 +8,14 @@ DV_CORE_BEGIN_NAMESPACE
|
|||||||
class MathUtil
|
class MathUtil
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static size_t ComponentSize(ComponentType ct);
|
static DV_CORE_API size_t ComponentSize(ComponentType ct);
|
||||||
static size_t DataTypeSize(DataType dt);
|
static DV_CORE_API size_t DataTypeSize(DataType dt);
|
||||||
|
static DV_CORE_API size_t PixelSize(PixelFormat pixelFormat);
|
||||||
|
|
||||||
|
//count the number of bits set in v
|
||||||
|
static DV_CORE_API uint32_t popcount(uint8_t v);
|
||||||
|
static DV_CORE_API uint32_t popcount(uint16_t v);
|
||||||
|
static DV_CORE_API uint32_t popcount(uint32_t v);
|
||||||
|
|
||||||
static bool floatEqual(float a, float b,
|
static bool floatEqual(float a, float b,
|
||||||
float tolerance = std::numeric_limits<float>::epsilon()) {
|
float tolerance = std::numeric_limits<float>::epsilon()) {
|
||||||
|
|||||||
@@ -94,6 +94,45 @@ public:
|
|||||||
template<typename U>
|
template<typename U>
|
||||||
friend TMatrix3<U> operator * (U fScalar, const TMatrix3<U>& rkMatrix);
|
friend TMatrix3<U> operator * (U fScalar, const TMatrix3<U>& rkMatrix);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static inline TMatrix3 makeTrans(T x, T y) {
|
||||||
|
return TMatrix3(
|
||||||
|
1, 0, x,
|
||||||
|
0, 1, y,
|
||||||
|
0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TMatrix3 makeTrans(const TVector2<T>& pos) {
|
||||||
|
return TMatrix3(
|
||||||
|
1, 0, pos.x,
|
||||||
|
0, 1, pos.y,
|
||||||
|
0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TMatrix3 makeScale(T x, T y) {
|
||||||
|
return TMatrix3(
|
||||||
|
x, 0, 0,
|
||||||
|
0, y, 0,
|
||||||
|
0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TMatrix3 makeScale(const TVector2<T>& scale) {
|
||||||
|
return TMatrix3(
|
||||||
|
scale.x, 0, 0,
|
||||||
|
0, scale.y, 0,
|
||||||
|
0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//2D rotate, left multiplication
|
||||||
|
static inline TMatrix3 makeRotate(T angle) {
|
||||||
|
T s = sin(angle);
|
||||||
|
T c = cos(angle);
|
||||||
|
return TMatrix3(
|
||||||
|
c, -s, 0,
|
||||||
|
s, c, 0,
|
||||||
|
0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Utilities
|
// Utilities
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline TVector2& operator = (const T* pScalar) {
|
||||||
|
x = pScalar[0];
|
||||||
|
y = pScalar[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool operator == (const TVector2& rkVector) const {
|
inline bool operator == (const TVector2& rkVector) const {
|
||||||
return (x == rkVector.x && y == rkVector.y);
|
return (x == rkVector.x && y == rkVector.y);
|
||||||
}
|
}
|
||||||
@@ -59,6 +65,18 @@ public:
|
|||||||
return (x != rkVector.x || y != rkVector.y);
|
return (x != rkVector.x || y != rkVector.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator > (const TVector2& rkVector) const {
|
||||||
|
if (y > rkVector.y) return true;
|
||||||
|
else if (y < rkVector.y) return false;
|
||||||
|
else return x > rkVector.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator < (const TVector2& rkVector) const {
|
||||||
|
if (y < rkVector.y) return true;
|
||||||
|
else if (y > rkVector.y) return false;
|
||||||
|
else return x < rkVector.x;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Arithmetic operations
|
// Arithmetic operations
|
||||||
inline TVector2 operator + (const TVector2& rkVector) const {
|
inline TVector2 operator + (const TVector2& rkVector) const {
|
||||||
@@ -172,14 +190,6 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator < (const TVector2& rhs) const {
|
|
||||||
return (x < rhs.x && y < rhs.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator > (const TVector2& rhs) const {
|
|
||||||
return (x > rhs.x && y > rhs.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline T length(void) const {
|
inline T length(void) const {
|
||||||
return MathUtil::sqrt(x * x + y * y);
|
return MathUtil::sqrt(x * x + y * y);
|
||||||
|
|||||||
@@ -62,6 +62,13 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline TVector3& operator = (const T* pScalar) {
|
||||||
|
x = pScalar[0];
|
||||||
|
y = pScalar[1];
|
||||||
|
z = pScalar[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool operator == (const TVector3& rkVector) const {
|
inline bool operator == (const TVector3& rkVector) const {
|
||||||
return (x == rkVector.x && y == rkVector.y && z == rkVector.z);
|
return (x == rkVector.x && y == rkVector.y && z == rkVector.z);
|
||||||
}
|
}
|
||||||
@@ -194,14 +201,6 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator < (const TVector3& rhs) const {
|
|
||||||
return (x < rhs.x && y < rhs.y && z < rhs.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator > (const TVector3& rhs) const {
|
|
||||||
return (x > rhs.x && y > rhs.y && z > rhs.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline T length(void) const {
|
inline T length(void) const {
|
||||||
return MathUtil::sqrt(x * x + y * y + z * z);
|
return MathUtil::sqrt(x * x + y * y + z * z);
|
||||||
|
|||||||
@@ -73,6 +73,14 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline TVector4& operator = (const T* pScalar) {
|
||||||
|
x = pScalar[0];
|
||||||
|
y = pScalar[1];
|
||||||
|
z = pScalar[2];
|
||||||
|
w = pScalar[4];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool operator == (const TVector4& rkVector) const {
|
inline bool operator == (const TVector4& rkVector) const {
|
||||||
return (x == rkVector.x && y == rkVector.y && z == rkVector.z && w == rkVector.w);
|
return (x == rkVector.x && y == rkVector.y && z == rkVector.z && w == rkVector.w);
|
||||||
}
|
}
|
||||||
@@ -210,14 +218,6 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator < (const TVector4& rhs) const {
|
|
||||||
return (x < rhs.x && y < rhs.y && z < rhs.z && w < rhs.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator > (const TVector4& rhs) const {
|
|
||||||
return (x > rhs.x && y > rhs.y && z > rhs.z && w > rhs.w);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline T dotProduct(const TVector4& vec) const {
|
inline T dotProduct(const TVector4& vec) const {
|
||||||
@@ -235,6 +235,11 @@ public:
|
|||||||
public:
|
public:
|
||||||
// special points
|
// special points
|
||||||
static DV_CORE_API const TVector4 ZERO;
|
static DV_CORE_API const TVector4 ZERO;
|
||||||
|
static DV_CORE_API const TVector4 ONE;
|
||||||
|
static DV_CORE_API const TVector4 UNIT_X;
|
||||||
|
static DV_CORE_API const TVector4 UNIT_Y;
|
||||||
|
static DV_CORE_API const TVector4 UNIT_Z;
|
||||||
|
static DV_CORE_API const TVector4 UNIT_W;
|
||||||
static DV_CORE_API const TVector4 WHITE;
|
static DV_CORE_API const TVector4 WHITE;
|
||||||
static DV_CORE_API const TVector4 BLACK;
|
static DV_CORE_API const TVector4 BLACK;
|
||||||
static DV_CORE_API const TVector4 RED;
|
static DV_CORE_API const TVector4 RED;
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "dvc_config.h"
|
|
||||||
#include "math/dvc_vector2.h"
|
|
||||||
#include "math/dvc_vector3.h"
|
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
class DV_CORE_API Rasterizer
|
|
||||||
{
|
|
||||||
//Draw Line
|
|
||||||
public:
|
|
||||||
typedef std::function<void(const std::pair<int32_t, int32_t>&, float)> DrawLineCallback;
|
|
||||||
|
|
||||||
//Bresenham's line algorithm
|
|
||||||
static void drawLine(int32_t canvasWidth, int32_t canvasHeight,
|
|
||||||
const fVector2& start, const fVector2& end,
|
|
||||||
DrawLineCallback callback);
|
|
||||||
|
|
||||||
//Draw Triangle
|
|
||||||
public:
|
|
||||||
typedef std::function<void(const std::pair<int32_t, int32_t>& pos, const fVector3& percent)> DrawTriangleCallback;
|
|
||||||
|
|
||||||
//Larrabee algorithm
|
|
||||||
static void drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
|
||||||
const fVector2& v0, const fVector2& v1, const fVector2& v2,
|
|
||||||
DrawTriangleCallback callback, bool ccw=true);
|
|
||||||
|
|
||||||
//Scaleline algorithm
|
|
||||||
static void drawTriangleScanline(int32_t canvasWidth, int32_t canvasHeight,
|
|
||||||
const fVector3& v0, const fVector3& v1, const fVector3& v2,
|
|
||||||
DrawTriangleCallback callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "scene/dvc_scene.h"
|
||||||
|
#include "device/dvc_uniform_buffer.h"
|
||||||
|
#include "device/dvc_render_target.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class DV_CORE_API RenderPipe
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Device& getDevice() {
|
||||||
|
return m_device;
|
||||||
|
}
|
||||||
|
const Device& getDevice() const {
|
||||||
|
return m_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
UniformBuffer& getUniformBuffer() {
|
||||||
|
return m_uniformBuffer;
|
||||||
|
}
|
||||||
|
const UniformBuffer& getUniformBuffer() const {
|
||||||
|
return m_uniformBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
AntiAliasingTech getAntiAliasingTech() const {
|
||||||
|
return m_aaTech;
|
||||||
|
}
|
||||||
|
void setAntiAliasingTech(AntiAliasingTech aaTech) {
|
||||||
|
m_aaTech = aaTech;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialPtr getDebugMaterial() const {
|
||||||
|
return m_debugMaterial;
|
||||||
|
}
|
||||||
|
void setDebugMaterial(MaterialPtr material) {
|
||||||
|
m_debugMaterial = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushRenderable(RenderableConstPtr renderable);
|
||||||
|
|
||||||
|
void process(RenderTarget& renderTarget);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Device& m_device;
|
||||||
|
AntiAliasingTech m_aaTech = AntiAliasingTech::AA_None;
|
||||||
|
UniformBuffer m_uniformBuffer;
|
||||||
|
RenderableArray m_renderableQueue;
|
||||||
|
MaterialPtr m_debugMaterial;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RenderPipe(Device& device);
|
||||||
|
~RenderPipe();
|
||||||
|
};
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "dvc_config.h"
|
|
||||||
#include "scene/dvc_scene.h"
|
|
||||||
#include "device/dvc_render_target.h"
|
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
class DV_CORE_API RenderQueue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void pushRenderable(RenderableConstPtr renderable);
|
|
||||||
|
|
||||||
size_t getRenderableCounts() const {
|
|
||||||
return m_queue.size();
|
|
||||||
}
|
|
||||||
RenderableConstPtr getRenderable(size_t index) const;
|
|
||||||
|
|
||||||
void build(const Scene& scene);
|
|
||||||
void process(UniformBuffer& uniformBuffer, RenderTarget& renderTarget);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::vector<RenderableConstPtr> m_queue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RenderQueue();
|
|
||||||
~RenderQueue();
|
|
||||||
};
|
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
|
||||||
+4
-7
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "dvc_config.h"
|
#include "dvc_config.h"
|
||||||
#include "math/dvc_matrix4.h"
|
#include "math/dvc_matrix4.h"
|
||||||
#include "dvc_render_queue.h"
|
#include "dvc_render_pipe.h"
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@@ -17,17 +17,14 @@ public:
|
|||||||
PrimitiveType primitiveType;
|
PrimitiveType primitiveType;
|
||||||
PrimitiveAttributes vertexData;
|
PrimitiveAttributes vertexData;
|
||||||
DeviceBufferAccessorConstPtr indices;
|
DeviceBufferAccessorConstPtr indices;
|
||||||
VertexShaderInterface* vs;
|
MaterialConstPtr material;
|
||||||
};
|
};
|
||||||
typedef std::vector<Node> NodeArray;
|
typedef std::vector<Node> NodeArray;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void process(const RenderQueue& renderQueue);
|
void process(const RenderableArray& renderableArray);
|
||||||
const NodeArray& getNodes(void) const {
|
|
||||||
return m_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
NodeArray m_nodes;
|
NodeArray m_nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
+3
-7
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dvc_config.h"
|
#include "dvc_config.h"
|
||||||
#include "dvc_render_step_IA.h"
|
#include "dvc_render_step0_input_assember.h"
|
||||||
#include "device/dvc_uniform_buffer.h"
|
#include "device/dvc_uniform_buffer.h"
|
||||||
#include "device/dvc_vertex_desc.h"
|
#include "device/dvc_vertex_desc.h"
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@ class VertexShaderStep
|
|||||||
public:
|
public:
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
|
MaterialConstPtr material;
|
||||||
DeviceBufferPtr vertexBuf;
|
DeviceBufferPtr vertexBuf;
|
||||||
VertexDesc vertexDesc;
|
VertexDesc vertexDesc;
|
||||||
size_t vertexCounts;
|
size_t vertexCounts;
|
||||||
@@ -21,14 +22,9 @@ public:
|
|||||||
typedef std::vector<Node> NodeArray;
|
typedef std::vector<Node> NodeArray;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const NodeArray& getNodes() const {
|
void process(RenderPipe& pipe, const InputAssemberStep::NodeArray& assembedNodeArray);
|
||||||
return m_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void process(UniformBuffer& uniformBuffer, const InputAssemberStep::NodeArray& assembedNodeArray);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
NodeArray m_nodes;
|
NodeArray m_nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "dvc_render_step1_vertex_shader.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class RasterizerStep
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Fragement
|
||||||
|
{
|
||||||
|
float32_t depth;
|
||||||
|
fVector4 color;
|
||||||
|
uint32_t mask;
|
||||||
|
int32_t next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<int32_t> StartOffsetArray;
|
||||||
|
typedef std::vector<Fragement> FragementArray;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void process(RenderPipe& pipe, const VertexShaderStep::NodeArray& vsNodeArray, AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight);
|
||||||
|
|
||||||
|
public:
|
||||||
|
StartOffsetArray m_startOffsetArray;
|
||||||
|
FragementArray m_fragementArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "dvc_render_step2_rasterizer.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class OutputMergerStep
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void process(const RasterizerStep::StartOffsetArray& startOffsetArray, const RasterizerStep::FragementArray& fragementArray,
|
||||||
|
AntiAliasingTech aaTech, RenderTarget& renderTarget);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void mergeFragement_without_AA(int32_t x, int32_t y,
|
||||||
|
const std::multimap<float32_t, int32_t>& fragementArrayMap,
|
||||||
|
const RasterizerStep::FragementArray& fragementArray, RenderTarget& renderTarget);
|
||||||
|
|
||||||
|
template<int32_t kSampleSize, uint32_t kSampleMask>
|
||||||
|
void mergeFragement_with_AA(int32_t x, int32_t y,
|
||||||
|
const std::multimap<float32_t, int32_t>& fragementArrayMap,
|
||||||
|
const RasterizerStep::FragementArray& fragementArray, RenderTarget& renderTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int32_t kSampleSize, uint32_t kSampleMask>
|
||||||
|
void OutputMergerStep::mergeFragement_with_AA(int32_t x, int32_t y, const std::multimap<float32_t, int32_t>& fragementArrayMap,
|
||||||
|
const RasterizerStep::FragementArray& fragementArray, RenderTarget& renderTarget)
|
||||||
|
{
|
||||||
|
if (fragementArrayMap.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (fragementArrayMap.size() == 1)
|
||||||
|
{
|
||||||
|
const RasterizerStep::Fragement& fragement = fragementArray[fragementArrayMap.begin()->second];
|
||||||
|
|
||||||
|
fVector4 finalColor = fragement.color;
|
||||||
|
finalColor.w = MathUtil::popcount((uint16_t)(fragement.mask & kSampleMask)) / (float32_t)kSampleSize;
|
||||||
|
|
||||||
|
renderTarget.setPixel(x, y, finalColor, fragement.depth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::array<int32_t, kSampleSize> samples;
|
||||||
|
samples.fill(-1);
|
||||||
|
|
||||||
|
float finalDepth = 0;
|
||||||
|
std::multimap<float32_t, int32_t>::const_iterator it, end = fragementArrayMap.end();
|
||||||
|
for (it = fragementArrayMap.begin(); it != end; ++it)
|
||||||
|
{
|
||||||
|
const RasterizerStep::Fragement& fragement = fragementArray[it->second];
|
||||||
|
for (int32_t k = 0; k < kSampleSize; k++)
|
||||||
|
{
|
||||||
|
if ((fragement.mask & (1 << k)) != 0)
|
||||||
|
{
|
||||||
|
samples[k] = it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finalDepth = fragement.depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
fVector3 finalColor(0.f, 0.f, 0.f);
|
||||||
|
int32_t bitCounts = 0;
|
||||||
|
for (int32_t k = 0; k < kSampleSize; k++)
|
||||||
|
{
|
||||||
|
int32_t fragementID = samples[k];
|
||||||
|
if (fragementID < 0 || fragementID >= fragementArray.size()) continue;
|
||||||
|
|
||||||
|
const RasterizerStep::Fragement& fragement = fragementArray[fragementID];
|
||||||
|
finalColor += fragement.color.xyz();
|
||||||
|
bitCounts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitCounts == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bitCounts > 1)
|
||||||
|
{
|
||||||
|
finalColor /= (float32_t)bitCounts;
|
||||||
|
}
|
||||||
|
float32_t finalAlpha = bitCounts / (float32_t)kSampleSize;
|
||||||
|
renderTarget.setPixel(x, y, fVector4(finalColor, finalAlpha), finalDepth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "dvc_config.h"
|
|
||||||
#include "dvc_render_step_VS.h"
|
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
class PixelShaderStep
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void process(const VertexShaderStep::NodeArray& vsNodeArray, RenderTarget& renderTarget);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "dvc_config.h"
|
#include "dvc_config.h"
|
||||||
#include "math/dvc_matrix4.h"
|
#include "math/dvc_matrix4.h"
|
||||||
#include "pipe/dvc_render_step_IA.h"
|
#include "pipe/dvc_render_step0_input_assember.h"
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "math/dvc_vector2.h"
|
||||||
|
#include "math/dvc_vector3.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class DV_CORE_API Rasterizer
|
||||||
|
{
|
||||||
|
//Draw Triangle with Larrabee
|
||||||
|
public:
|
||||||
|
typedef std::function<
|
||||||
|
void(const std::pair<int32_t, int32_t>& pos, const fVector3& percent, uint32_t mask)
|
||||||
|
> DrawTriangleCallback;
|
||||||
|
|
||||||
|
struct DebugParam
|
||||||
|
{
|
||||||
|
bool debug;
|
||||||
|
const char* szOutputFileName;
|
||||||
|
int32_t x;
|
||||||
|
int32_t y;
|
||||||
|
|
||||||
|
FILE* fpOutput;
|
||||||
|
int32_t tile_id;
|
||||||
|
int32_t coarse_id;
|
||||||
|
int32_t fine_id;
|
||||||
|
int32_t edge_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Larrabee algorithm
|
||||||
|
static void drawTriangleLarrabee(AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight,
|
||||||
|
const fVector2& v0, const fVector2& v1, const fVector2& v2,
|
||||||
|
DrawTriangleCallback callback, bool ccw=true,
|
||||||
|
const DebugParam* debugParam=nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
//BoundingBox algorithm
|
||||||
|
static void drawTriangleBoundingBox(int32_t canvasWidth, int32_t canvasHeight,
|
||||||
|
const fVector2& v0, const fVector2& v1, const fVector2& v2,
|
||||||
|
DrawTriangleCallback callback, bool ccw = true);
|
||||||
|
};
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
virtual const std::string& getTypeName() const { return typeName(); }
|
virtual const std::string& getTypeName() const { return typeName(); }
|
||||||
virtual void render(const fMatrix4& transParent, RenderQueue& queue) const;
|
virtual void buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe) const;
|
||||||
|
|
||||||
fVector3 getEye(void) const;
|
fVector3 getEye(void) const;
|
||||||
fVector3 getLookat(void) const;
|
fVector3 getLookat(void) const;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class DV_CORE_API SceneComponent
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const std::string& getTypeName() const = 0;
|
virtual const std::string& getTypeName() const = 0;
|
||||||
virtual void render(const fMatrix4& transParent, RenderQueue& queue) const;
|
virtual void buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SceneNodePtr m_owner;
|
SceneNodePtr m_owner;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public:
|
|||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
virtual const std::string& getTypeName() const { return typeName(); }
|
virtual const std::string& getTypeName() const { return typeName(); }
|
||||||
virtual void render(const fMatrix4& transParent, RenderQueue& queue) const;
|
virtual void buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe) const;
|
||||||
|
|
||||||
void setLightDefine(const LightDefine& lightDefine);
|
void setLightDefine(const LightDefine& lightDefine);
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class DV_CORE_API MeshComponent : public SceneComponent
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const std::string& getTypeName() const { return typeName(); }
|
virtual const std::string& getTypeName() const { return typeName(); }
|
||||||
virtual void render(const fMatrix4& transParent, RenderQueue& queue) const;
|
virtual void buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe) const;
|
||||||
|
|
||||||
void setMesh(MeshConstPtr mesh);
|
void setMesh(MeshConstPtr mesh);
|
||||||
|
|
||||||
|
|||||||
@@ -11,35 +11,10 @@ public:
|
|||||||
void init(void);
|
void init(void);
|
||||||
void clear(void);
|
void clear(void);
|
||||||
|
|
||||||
public:
|
|
||||||
DeviceBufferPtr newDeviceBuffer(void);
|
|
||||||
int32_t getDeviceBufferCounts(void) const {
|
|
||||||
return (int32_t)m_deviceBufferArray.size();
|
|
||||||
}
|
|
||||||
DeviceBufferConstPtr getDeviceBuffer(int32_t index) const;
|
|
||||||
|
|
||||||
DeviceBufferViewPtr newDeviceBufferView(DeviceBufferConstPtr buffer, size_t offset, size_t length, size_t stride);
|
|
||||||
int32_t getDeviceBufferViewCounts(void) const {
|
|
||||||
return (int32_t)m_bufferViewArray.size();
|
|
||||||
}
|
|
||||||
DeviceBufferViewPtr getDeviceBufferView(int32_t index) const;
|
|
||||||
|
|
||||||
DeviceBufferAccessorPtr newDeviceBufferAccessor(DeviceBufferViewConstPtr bufferView, size_t offset,
|
|
||||||
size_t count, ComponentType componentType, DataType dataType);
|
|
||||||
int32_t getDeviceBufferAccessorCounts(void) const {
|
|
||||||
return (int32_t)m_bufferAccessorArray.size();
|
|
||||||
}
|
|
||||||
DeviceBufferAccessorPtr getDeviceBufferAccessor(int32_t index) const;
|
|
||||||
|
|
||||||
int32_t pushNewMeshAsset(MeshPtr mesh);
|
|
||||||
int32_t getMeshCounts(void) const {
|
|
||||||
return (int32_t)m_meshArray.size();
|
|
||||||
}
|
|
||||||
MeshConstPtr getMesh(int32_t index) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SceneNodePtr newSceneNode(const std::string& name);
|
SceneNodePtr newSceneNode(const std::string& name);
|
||||||
SceneNodePtr getRootSceneNode() const;
|
SceneNodePtr getRootSceneNode() const;
|
||||||
|
void buildRenderableQueue(RenderPipe& pipe) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename ComponentType>
|
template<typename ComponentType>
|
||||||
@@ -79,14 +54,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
SceneNodePtr m_rootSceneNode;
|
SceneNodePtr m_rootSceneNode;
|
||||||
|
|
||||||
//device resources
|
|
||||||
std::vector<DeviceBufferPtr> m_deviceBufferArray;
|
|
||||||
std::vector<DeviceBufferViewPtr> m_bufferViewArray;
|
|
||||||
std::vector<DeviceBufferAccessorPtr> m_bufferAccessorArray;
|
|
||||||
|
|
||||||
//asset resources
|
|
||||||
std::vector<MeshPtr> m_meshArray;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Scene();
|
Scene();
|
||||||
~Scene();
|
~Scene();
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void buildRenderQueue(const fMatrix4& transParent, RenderQueue& queue);
|
void buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "dvc_pre_declare.h"
|
||||||
|
#include "math/dvc_vector2.h"
|
||||||
|
#include "math/dvc_vector4.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
static inline int32_t step(const T& edge, const T& x) {
|
||||||
|
return (x >= edge) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T max(const T& a, const T& b) {
|
||||||
|
return (a > b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T pow(const T& base, const T& exponent) {
|
||||||
|
return std::pow(base, exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T min(const T& a, const T& b) {
|
||||||
|
return (a < b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DV_CORE_API fVector4 texture2D(const RenderPipe& pipe, const TextureInfo& texturePtr, const fVector2& uv, const fVector4& defaultValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "dvc_config.h"
|
#include "dvc_config.h"
|
||||||
#include "dvc_pre_declare.h"
|
#include "dvc_pre_declare.h"
|
||||||
|
#include "math/dvc_vector2.h"
|
||||||
#include "math/dvc_vector3.h"
|
#include "math/dvc_vector3.h"
|
||||||
#include "math/dvc_vector4.h"
|
#include "math/dvc_vector4.h"
|
||||||
#include "device/dvc_vertex_desc.h"
|
#include "device/dvc_vertex_desc.h"
|
||||||
@@ -15,27 +16,30 @@ public:
|
|||||||
virtual const VertexDesc& getOutputVertexDesc() const = 0;
|
virtual const VertexDesc& getOutputVertexDesc() const = 0;
|
||||||
|
|
||||||
typedef std::function<DeviceBufferAccessorConstPtr(VertexElementType)> SetInputAttributeFunc;
|
typedef std::function<DeviceBufferAccessorConstPtr(VertexElementType)> SetInputAttributeFunc;
|
||||||
virtual void prepare(const UniformBuffer* uniformBuffer, SetInputAttributeFunc setInputAttributeFunc) = 0;
|
virtual void begin(const RenderPipe* pipe, SetInputAttributeFunc setInputAttributeFunc) = 0;
|
||||||
|
|
||||||
virtual void process(size_t index, void* outputVertex, fVector3& vertexWorldPos) = 0;
|
virtual void process(size_t index, float32_t* outputVertex) = 0;
|
||||||
|
|
||||||
|
virtual void end() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PixelShaderInterface
|
class FragementShaderInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const char* getName(void) const = 0;
|
virtual const char* getName(void) const = 0;
|
||||||
|
|
||||||
typedef std::function<size_t(const std::string&)> SetInputAttributeFunc;
|
virtual bool begin(const RenderPipe* pipe, MaterialConstPtr material, const VertexDesc& veretexDesc) = 0;
|
||||||
virtual void prepare(const UniformBuffer* uniformBuffer, SetInputAttributeFunc setInputAttributeFunc) = 0;
|
|
||||||
|
|
||||||
virtual void process(const VertexDesc& veretexDesc, const float32_t* pixelData, fVector4& color) = 0;
|
virtual void process(const float32_t* pixelData, fVector4& color) = 0;
|
||||||
|
|
||||||
|
virtual void end() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShaderFileInterface
|
class ShaderFileInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual VertexShaderInterface* getVertexShader(const char* szName) = 0;
|
virtual VertexShaderInterface* getVertexShader(const char* szName) = 0;
|
||||||
virtual PixelShaderInterface* getPixelShader(const char* szName) = 0;
|
virtual FragementShaderInterface* getFragementShader(const char* szName) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ShaderFileInterface* (*ShaderFileInterfaceFunc)();
|
typedef ShaderFileInterface* (*ShaderFileInterfaceFunc)();
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#include "asset/dvc_image.h"
|
||||||
|
#include "math/dvc_math_util.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "device/dvc_buffer.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Image::Image(int32_t id)
|
||||||
|
: m_id(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::~Image()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::clear()
|
||||||
|
{
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
|
m_pixelFormat = PF_UNKNOWN;
|
||||||
|
m_pixelByteSize = 0;
|
||||||
|
m_pixelBuffer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fVector4 Image::getPixel(int32_t u, int32_t v) const
|
||||||
|
{
|
||||||
|
if(u<0 || u>=m_width || v<0 || v>=m_height)
|
||||||
|
{
|
||||||
|
return fVector4::ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t* p = (const uint8_t*)(m_pixelBuffer->ptr(0)) + (v * m_width + u) * m_pixelByteSize;
|
||||||
|
switch (m_pixelFormat)
|
||||||
|
{
|
||||||
|
case PF_UINT8_ALPHA:
|
||||||
|
return fVector4(0, 0, 0, p[0] / 255.0f);
|
||||||
|
case PF_UINT8_RGB:
|
||||||
|
return fVector4(p[0] / 255.0f, p[1] / 255.0f, p[2] / 255.0f, 1.0f);
|
||||||
|
case PF_UINT8_RGBA:
|
||||||
|
return fVector4(p[0] / 255.0f, p[1] / 255.0f, p[2] / 255.0f, p[3] / 255.0f);
|
||||||
|
case PF_FLOAT32_ALPHA:
|
||||||
|
return fVector4(0, 0, 0, *((const float*)p));
|
||||||
|
case PF_FLOAT32_RGB:
|
||||||
|
{
|
||||||
|
const float* fp = (const float*)p;
|
||||||
|
return fVector4(fp[0], fp[1], fp[2], 1.0f);
|
||||||
|
}
|
||||||
|
case PF_FLOAT32_RGBA:
|
||||||
|
{
|
||||||
|
const float* fp = (const float*)p;
|
||||||
|
return fVector4(fp[0], fp[1], fp[2], fp[3]);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fVector4::ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Image::initWithPixelData(Device& device, int32_t width, int32_t height,
|
||||||
|
PixelFormat pixelFormat, const uint8_t* data, size_t dataSize)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
size_t pixelByteSize = MathUtil::PixelSize(pixelFormat);
|
||||||
|
if (dataSize != pixelByteSize*width*height)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
|
m_pixelFormat = pixelFormat;
|
||||||
|
m_pixelByteSize = pixelByteSize;
|
||||||
|
m_pixelBuffer = device.newDeviceBuffer(dataSize);
|
||||||
|
memcpy(m_pixelBuffer->ptr(0), data, dataSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include "asset/dvc_material.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Material::Material(int32_t id, const char* name)
|
||||||
|
: m_id(id)
|
||||||
|
, m_name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Material::~Material()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::setVertexShader(const char* szShaderFile, const char* vertexShaderName)
|
||||||
|
{
|
||||||
|
m_vertexshaderFile = szShaderFile;
|
||||||
|
m_vertexShaderName = vertexShaderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::setFragementShader(const char* szShaderFile, const char* fragementShaderName)
|
||||||
|
{
|
||||||
|
m_fragementShaderFile = szShaderFile;
|
||||||
|
m_fragementShaderName = fragementShaderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Material::setupMaterial()
|
||||||
|
{
|
||||||
|
ShaderFileInterface* shaderInterface = davinci::LoadShaderFile(m_vertexshaderFile.c_str());
|
||||||
|
if (shaderInterface == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_vertexShader = shaderInterface->getVertexShader(m_vertexShaderName.c_str());
|
||||||
|
if (!m_vertexShader)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shaderInterface = davinci::LoadShaderFile(m_fragementShaderFile.c_str());
|
||||||
|
if (shaderInterface == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fragementShader = shaderInterface->getFragementShader(m_fragementShaderName.c_str());
|
||||||
|
if (!m_fragementShader)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
Mesh::Mesh(const std::string& name)
|
Mesh::Mesh(int32_t id, const std::string& name)
|
||||||
: m_name(name)
|
: m_id(id)
|
||||||
|
, m_name(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#include "asset/dvc_texture.h"
|
||||||
|
#include "math/dvc_math_util.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "device/dvc_buffer.h"
|
||||||
|
#include "asset/dvc_image.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Texture::Texture(int32_t id)
|
||||||
|
: m_id(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture::~Texture()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fVector4 Texture::sample(const fVector2& uv) const
|
||||||
|
{
|
||||||
|
fVector4 color = fVector4::ZERO;
|
||||||
|
if (!m_image) return color;
|
||||||
|
|
||||||
|
float uv_x = uv.x - std::floor(uv.x);
|
||||||
|
float uv_y = uv.y - std::floor(uv.y);
|
||||||
|
|
||||||
|
|
||||||
|
int32_t u = uv_x * m_image->getWidth();
|
||||||
|
int32_t v = uv_y * m_image->getHeight();
|
||||||
|
|
||||||
|
return m_image->getPixel(u, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -2,14 +2,9 @@
|
|||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
DeviceBuffer::DeviceBuffer()
|
DeviceBuffer::DeviceBuffer(int32_t id, size_t _length)
|
||||||
: m_ptr(nullptr)
|
: m_id(id)
|
||||||
, m_length(0)
|
, m_ptr(nullptr)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceBuffer::DeviceBuffer(size_t _length)
|
|
||||||
: m_ptr(nullptr)
|
|
||||||
, m_length(0)
|
, m_length(0)
|
||||||
{
|
{
|
||||||
init(_length);
|
init(_length);
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
DeviceBufferAccessor::DeviceBufferAccessor(DeviceBufferViewConstPtr bufferView, size_t offset, size_t count, ComponentType componentType, DataType dataType)
|
DeviceBufferAccessor::DeviceBufferAccessor(int32_t id, DeviceBufferViewConstPtr bufferView, size_t offset, size_t count, ComponentType componentType, DataType dataType)
|
||||||
: m_bufferView(bufferView)
|
: m_id(id)
|
||||||
|
, m_bufferView(bufferView)
|
||||||
, m_offset(offset)
|
, m_offset(offset)
|
||||||
, m_count(count)
|
, m_count(count)
|
||||||
, m_componentType(componentType)
|
, m_componentType(componentType)
|
||||||
@@ -25,10 +26,11 @@ void DeviceBufferAccessor::walk(std::function<bool(const uint8_t*, size_t)> call
|
|||||||
|
|
||||||
DeviceBufferConstPtr buffer = m_bufferView->getBuffer();
|
DeviceBufferConstPtr buffer = m_bufferView->getBuffer();
|
||||||
const uint8_t* ptr = buffer->ptr(m_bufferView->getOffset()) + m_offset;
|
const uint8_t* ptr = buffer->ptr(m_bufferView->getOffset()) + m_offset;
|
||||||
|
const size_t step = m_bufferView->getStride() > 0 ? m_bufferView->getStride() : m_elementSize;
|
||||||
|
|
||||||
size_t startIndex = start;
|
size_t startIndex = start;
|
||||||
size_t endIndex = (end == ((size_t)-1)) ? m_count : end;
|
size_t endIndex = (end == ((size_t)-1)) ? m_count : end;
|
||||||
for (size_t index = startIndex; index < endIndex; index++, ptr+=m_elementSize)
|
for (size_t index = startIndex; index < endIndex; index++, ptr+=step)
|
||||||
{
|
{
|
||||||
if (callback(ptr, index))
|
if (callback(ptr, index))
|
||||||
{
|
{
|
||||||
@@ -44,12 +46,13 @@ void DeviceBufferAccessor::walk2(std::function<bool(const uint8_t*, const uint8_
|
|||||||
|
|
||||||
DeviceBufferConstPtr buffer = m_bufferView->getBuffer();
|
DeviceBufferConstPtr buffer = m_bufferView->getBuffer();
|
||||||
const uint8_t* ptr = buffer->ptr(m_bufferView->getOffset()) + m_offset;
|
const uint8_t* ptr = buffer->ptr(m_bufferView->getOffset()) + m_offset;
|
||||||
|
const size_t step = m_bufferView->getStride() > 0 ? m_bufferView->getStride() : m_elementSize;
|
||||||
|
|
||||||
size_t startIndex = start;
|
size_t startIndex = start;
|
||||||
size_t endIndex = (end == ((size_t)-1)) ? m_count : end;
|
size_t endIndex = (end == ((size_t)-1)) ? m_count : end;
|
||||||
for (size_t index = startIndex; index < endIndex; index+=2, ptr+=m_elementSize*2)
|
for (size_t index = startIndex; index < endIndex; index+=2, ptr+=step*2)
|
||||||
{
|
{
|
||||||
if (callback(ptr, ((index + 1) < endIndex) ? (ptr + m_elementSize) : nullptr, index))
|
if (callback(ptr, ((index + 1) < endIndex) ? (ptr + step) : nullptr, index))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -63,14 +66,15 @@ void DeviceBufferAccessor::walk3(std::function<bool(const uint8_t*, const uint8_
|
|||||||
|
|
||||||
DeviceBufferConstPtr buffer = m_bufferView->getBuffer();
|
DeviceBufferConstPtr buffer = m_bufferView->getBuffer();
|
||||||
const uint8_t* ptr = buffer->ptr(m_bufferView->getOffset()) + m_offset;
|
const uint8_t* ptr = buffer->ptr(m_bufferView->getOffset()) + m_offset;
|
||||||
|
const size_t step = m_bufferView->getStride() > 0 ? m_bufferView->getStride() : m_elementSize;
|
||||||
|
|
||||||
size_t startIndex = start;
|
size_t startIndex = start;
|
||||||
size_t endIndex = (end == ((size_t)-1)) ? m_count : end;
|
size_t endIndex = (end == ((size_t)-1)) ? m_count : end;
|
||||||
for (size_t index = startIndex; index < endIndex; index += 3, ptr += m_elementSize * 3)
|
for (size_t index = startIndex; index < endIndex; index += 3, ptr += step * 3)
|
||||||
{
|
{
|
||||||
if(callback(ptr,
|
if(callback(ptr,
|
||||||
((index + 1) < endIndex) ? (ptr + m_elementSize) : nullptr,
|
((index + 1) < endIndex) ? (ptr + step) : nullptr,
|
||||||
((index + 2) < endIndex) ? (ptr + m_elementSize*2) : nullptr,
|
((index + 2) < endIndex) ? (ptr + step*2) : nullptr,
|
||||||
index))
|
index))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -85,7 +89,9 @@ const uint8_t* DeviceBufferAccessor::getElement(size_t index) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeviceBufferConstPtr buffer = m_bufferView->getBuffer();
|
DeviceBufferConstPtr buffer = m_bufferView->getBuffer();
|
||||||
const uint8_t* pData = buffer->ptr(m_bufferView->getOffset()) + m_offset + index * m_elementSize;
|
const uint8_t* pData = buffer->ptr(m_bufferView->getOffset())
|
||||||
|
+ m_offset
|
||||||
|
+ index * (m_bufferView->getStride()>0 ? m_bufferView->getStride(): m_elementSize);
|
||||||
|
|
||||||
return pData;
|
return pData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
DeviceBufferView::DeviceBufferView(DeviceBufferConstPtr buffer, size_t offset, size_t length, size_t stride)
|
DeviceBufferView::DeviceBufferView(int32_t id, DeviceBufferConstPtr buffer, size_t offset, size_t length, size_t stride)
|
||||||
: m_buffer(buffer)
|
: m_id(id)
|
||||||
|
, m_buffer(buffer)
|
||||||
, m_offset(offset)
|
, m_offset(offset)
|
||||||
, m_length(length)
|
, m_length(length)
|
||||||
, m_stride(stride)
|
, m_stride(stride)
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "device/dvc_buffer.h"
|
||||||
|
#include "device/dvc_buffer_view.h"
|
||||||
|
#include "device/dvc_buffer_accessor.h"
|
||||||
|
#include "asset/dvc_mesh.h"
|
||||||
|
#include "asset/dvc_image.h"
|
||||||
|
#include "asset/dvc_texture.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Device::Device()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Device::~Device()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::clear(void)
|
||||||
|
{
|
||||||
|
//clear assets
|
||||||
|
m_meshAssetMap.clear();
|
||||||
|
m_imageAssetMap.clear();
|
||||||
|
|
||||||
|
//clear device resources
|
||||||
|
m_bufferAccessorMap.clear();
|
||||||
|
m_bufferViewMap.clear();
|
||||||
|
m_deviceBufferMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceBufferPtr Device::newDeviceBuffer(size_t length)
|
||||||
|
{
|
||||||
|
DeviceBufferPtr deviceBuffer = std::make_shared<DeviceBuffer>(nextID(), length);
|
||||||
|
|
||||||
|
m_deviceBufferMap.insert(std::make_pair(deviceBuffer->getID(), deviceBuffer));
|
||||||
|
return deviceBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceBufferConstPtr Device::getDeviceBuffer(int32_t id) const
|
||||||
|
{
|
||||||
|
std::map<int32_t, DeviceBufferPtr>::const_iterator it = m_deviceBufferMap.find(id);
|
||||||
|
if(it==m_deviceBufferMap.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceBufferViewPtr Device::newDeviceBufferView(DeviceBufferConstPtr buffer, size_t offset, size_t length, size_t stride)
|
||||||
|
{
|
||||||
|
DeviceBufferViewPtr deviceBufferView = std::make_shared<DeviceBufferView>(nextID(), buffer, offset, length, stride);
|
||||||
|
m_bufferViewMap.insert(std::make_pair(deviceBufferView->getID(), deviceBufferView));
|
||||||
|
return deviceBufferView;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceBufferViewPtr Device::getDeviceBufferView(int32_t id) const
|
||||||
|
{
|
||||||
|
std::map<int32_t, DeviceBufferViewPtr>::const_iterator it = m_bufferViewMap.find(id);
|
||||||
|
if(it==m_bufferViewMap.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceBufferAccessorPtr Device::newDeviceBufferAccessor(DeviceBufferViewConstPtr bufferView, size_t offset,
|
||||||
|
size_t count, ComponentType componentType, DataType dataType)
|
||||||
|
{
|
||||||
|
DeviceBufferAccessorPtr deviceBufferAccessor = std::make_shared<DeviceBufferAccessor>(
|
||||||
|
nextID(), bufferView, offset, count, componentType, dataType);
|
||||||
|
m_bufferAccessorMap.insert(std::make_pair(deviceBufferAccessor->getID(), deviceBufferAccessor));
|
||||||
|
return deviceBufferAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceBufferAccessorPtr Device::getDeviceBufferAccessor(int32_t id) const
|
||||||
|
{
|
||||||
|
std::map<int32_t, DeviceBufferAccessorPtr>::const_iterator it = m_bufferAccessorMap.find(id);
|
||||||
|
if(it==m_bufferAccessorMap.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshPtr Device::newMeshAsset(const std::string& name)
|
||||||
|
{
|
||||||
|
MeshPtr meshPtr = std::make_shared<davinci::Mesh>(nextID(), name);
|
||||||
|
m_meshAssetMap.insert(std::make_pair(meshPtr->getID(), meshPtr));
|
||||||
|
return meshPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshPtr Device::getMesh(int32_t id) const
|
||||||
|
{
|
||||||
|
std::map<int32_t, MeshPtr>::const_iterator it = m_meshAssetMap.find(id);
|
||||||
|
if(it==m_meshAssetMap.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagePtr Device::newImageAsset()
|
||||||
|
{
|
||||||
|
ImagePtr imagePtr = std::make_shared<Image>(nextID());
|
||||||
|
m_imageAssetMap.insert(std::make_pair(imagePtr->getID(), imagePtr));
|
||||||
|
return imagePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagePtr Device::getImage(int32_t id) const
|
||||||
|
{
|
||||||
|
std::map<int32_t, ImagePtr>::const_iterator it = m_imageAssetMap.find(id);
|
||||||
|
if(it==m_imageAssetMap.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
TexturePtr Device::newTextureAsset()
|
||||||
|
{
|
||||||
|
TexturePtr texturePtr = std::make_shared<Texture>(nextID());
|
||||||
|
m_textureAssetMap.insert(std::make_pair(texturePtr->getID(), texturePtr));
|
||||||
|
return texturePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TexturePtr Device::getTexture(int32_t id) const
|
||||||
|
{
|
||||||
|
std::map<int32_t, TexturePtr>::const_iterator it = m_textureAssetMap.find(id);
|
||||||
|
if(it==m_textureAssetMap.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialPtr Device::getMaterial(int32_t id) const
|
||||||
|
{
|
||||||
|
std::map<int32_t, MaterialPtr>::const_iterator it = m_materialAssetMap.find(id);
|
||||||
|
if(it==m_materialAssetMap.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -16,7 +16,7 @@ void RenderTarget::init(int32_t width, int32_t height)
|
|||||||
|
|
||||||
void RenderTarget::clear()
|
void RenderTarget::clear()
|
||||||
{
|
{
|
||||||
m_colorBuffer.clear(fVector4::BLACK);
|
m_colorBuffer.clear(fVector4(0.f, 0.f, 0.f, 0.f));
|
||||||
m_depthBuffer.clear(std::numeric_limits<float32_t>::max());
|
m_depthBuffer.clear(std::numeric_limits<float32_t>::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,9 +24,6 @@ void RenderTarget::setPixel(int32_t x, int32_t y, const fVector4& color, float32
|
|||||||
{
|
{
|
||||||
if (x < 0 || x >= m_width || y < 0 || y >= m_height) return;
|
if (x < 0 || x >= m_width || y < 0 || y >= m_height) return;
|
||||||
|
|
||||||
if (depth > m_depthBuffer.getPixel(x, y)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_colorBuffer.setPixel(x, y, color);
|
m_colorBuffer.setPixel(x, y, color);
|
||||||
m_depthBuffer.setPixel(x, y, depth);
|
m_depthBuffer.setPixel(x, y, depth);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ bool VertexDesc::addElement(const std::string& name, VertexElementType elementTy
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexDesc::Element* VertexDesc::getElement(size_t index) const
|
const VertexDesc::Element* VertexDesc::getElementByIndex(size_t index) const
|
||||||
{
|
{
|
||||||
if (index >= m_elements.size())
|
if (index >= m_elements.size())
|
||||||
{
|
{
|
||||||
@@ -84,24 +84,24 @@ const VertexDesc::Element* VertexDesc::getElement(size_t index) const
|
|||||||
return &(m_elements[index]);
|
return &(m_elements[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexDesc::Element* VertexDesc::getElement(VertexElementType type) const
|
const VertexDesc::Element* VertexDesc::getElementByType(VertexElementType type) const
|
||||||
{
|
{
|
||||||
auto it = m_elementTypeMap.find(type);
|
auto it = m_elementTypeMap.find(type);
|
||||||
if (it == m_elementTypeMap.end())
|
if (it == m_elementTypeMap.end())
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return getElement(it->second);
|
return getElementByIndex(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexDesc::Element* VertexDesc::getElement(const std::string& name) const
|
const VertexDesc::Element* VertexDesc::getElementByName(const std::string& name) const
|
||||||
{
|
{
|
||||||
auto it = m_nameMap.find(name);
|
auto it = m_nameMap.find(name);
|
||||||
if (it == m_nameMap.end())
|
if (it == m_nameMap.end())
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return getElement(it->second);
|
return getElementByIndex(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
DV_CORE_END_NAMESPACE
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#include "math/dvc_fix_point.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
const ifloat64 ifloat64::kMax{ ifloat64::kMax_s3132 };
|
||||||
|
const ifloat64 ifloat64::kMin{ ifloat64::kMin_s3132 };
|
||||||
|
const ifloat64 ifloat64::kZero{ 0 };
|
||||||
|
const ifloat64 ifloat64::kOne{ INT64_C(1) << ifloat64::kShift };
|
||||||
|
const ifloat64 ifloat64::kTwo{ INT64_C(2) << kShift };
|
||||||
|
const ifloat64 ifloat64::kThree{ INT64_C(3) << ifloat64::kShift };
|
||||||
|
const ifloat64 ifloat64::kFour{ INT64_C(4) << ifloat64::kShift };
|
||||||
|
const ifloat64 ifloat64::kHalf{ INT64_C(1) << (ifloat64::kShift-1) };
|
||||||
|
const ifloat64 ifloat64::kQuater{ INT64_C(1) << (ifloat64::kShift - 2) };
|
||||||
|
const ifloat64 ifloat64::kOneEighth{ INT64_C(1) << (ifloat64::kShift - 3) };
|
||||||
|
const ifloat64 ifloat64::kPi{ INT64_C(0x3243f6a89) }; //static_cast<int64_t>(std::round(M_PI * kFloatScale));
|
||||||
|
const ifloat64 ifloat64::kPi2{ INT64_C(0x6487ed511) };
|
||||||
|
const ifloat64 ifloat64::kPiHalf{ INT64_C(0x1921fb544) };
|
||||||
|
const ifloat64 ifloat64::kE{ INT64_C(0x2b7e15163) };
|
||||||
|
const ifloat64 ifloat64::kNegOne{ INT64_C(-1) << kShift };
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
|
|
||||||
@@ -11,6 +11,31 @@ const float MathUtil::PI_DIV4 = float(0.25 * PI);
|
|||||||
const float MathUtil::fDeg2Rad = PI / float(180.0);
|
const float MathUtil::fDeg2Rad = PI / float(180.0);
|
||||||
const float MathUtil::fRad2Deg = float(180.0) / PI;
|
const float MathUtil::fRad2Deg = float(180.0) / PI;
|
||||||
|
|
||||||
|
static const uint8_t kBitsSetTable256[256] =
|
||||||
|
{
|
||||||
|
#define B2(n) n, n+1, n+1, n+2
|
||||||
|
#define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
|
||||||
|
#define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
|
||||||
|
|
||||||
|
B6(0), B6(1), B6(1), B6(2)
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t MathUtil::popcount(uint8_t v)
|
||||||
|
{
|
||||||
|
return kBitsSetTable256[v];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MathUtil::popcount(uint16_t v)
|
||||||
|
{
|
||||||
|
return kBitsSetTable256[v & 0xff] + kBitsSetTable256[(v >> 8) & 0xff];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MathUtil::popcount(uint32_t v)
|
||||||
|
{
|
||||||
|
return kBitsSetTable256[v & 0xff] + kBitsSetTable256[(v >> 8) & 0xff] +
|
||||||
|
kBitsSetTable256[(v >> 16) & 0xff] + kBitsSetTable256[v >> 24];
|
||||||
|
}
|
||||||
|
|
||||||
size_t MathUtil::ComponentSize(ComponentType ct)
|
size_t MathUtil::ComponentSize(ComponentType ct)
|
||||||
{
|
{
|
||||||
switch (ct)
|
switch (ct)
|
||||||
@@ -64,6 +89,35 @@ size_t MathUtil::DataTypeSize(DataType dt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t MathUtil::PixelSize(PixelFormat pixelFormat)
|
||||||
|
{
|
||||||
|
switch (pixelFormat)
|
||||||
|
{
|
||||||
|
case PixelFormat::PF_UINT8_ALPHA:
|
||||||
|
return 1;
|
||||||
|
case PixelFormat::PF_UINT8_RGB:
|
||||||
|
return 3;
|
||||||
|
case PixelFormat::PF_UINT8_RGBA:
|
||||||
|
return 4;
|
||||||
|
case PixelFormat::PF_UINT16_ALPHA:
|
||||||
|
return 2;
|
||||||
|
case PixelFormat::PF_UINT16_RGB:
|
||||||
|
return 6;
|
||||||
|
case PixelFormat::PF_UINT16_RGBA:
|
||||||
|
return 8;
|
||||||
|
case PixelFormat::PF_FLOAT32_ALPHA:
|
||||||
|
return 4;
|
||||||
|
case PixelFormat::PF_FLOAT32_RGB:
|
||||||
|
return 12;
|
||||||
|
case PixelFormat::PF_FLOAT32_RGBA:
|
||||||
|
return 16;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
float MathUtil::unitRandom(void)
|
float MathUtil::unitRandom(void)
|
||||||
{
|
{
|
||||||
return float(rand()) / RAND_MAX;
|
return float(rand()) / RAND_MAX;
|
||||||
|
|||||||
@@ -4,6 +4,11 @@ DV_CORE_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
|
|
||||||
const fVector4 fVector4::ZERO(0, 0, 0, 0);
|
const fVector4 fVector4::ZERO(0, 0, 0, 0);
|
||||||
|
const fVector4 fVector4::ONE(1, 1, 1, 1);
|
||||||
|
const fVector4 fVector4::UNIT_X(1, 0, 0, 0);
|
||||||
|
const fVector4 fVector4::UNIT_Y(0, 1, 0, 0);
|
||||||
|
const fVector4 fVector4::UNIT_Z(0, 0, 1, 0);
|
||||||
|
const fVector4 fVector4::UNIT_W(0, 0, 0, 1);
|
||||||
const fVector4 fVector4::WHITE(1, 1, 1, 1);
|
const fVector4 fVector4::WHITE(1, 1, 1, 1);
|
||||||
const fVector4 fVector4::BLACK(0, 0, 0, 1);
|
const fVector4 fVector4::BLACK(0, 0, 0, 1);
|
||||||
const fVector4 fVector4::RED(1, 0, 0, 1);
|
const fVector4 fVector4::RED(1, 0, 0, 1);
|
||||||
|
|||||||
@@ -1,496 +0,0 @@
|
|||||||
#include "pipe/dvc_rasterizer.h"
|
|
||||||
#include "math/dvc_fixmath.h"
|
|
||||||
#include "math/dvc_math_util.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
https://github.com/nlguillemot/vigilant-system
|
|
||||||
https://wiki.joak.org/public:cs:rasterization_on_larrabee
|
|
||||||
*/
|
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
struct DrawTriangleParam
|
|
||||||
{
|
|
||||||
int32_t widthInTiles;
|
|
||||||
bool ccw;
|
|
||||||
fVector2 verts[3];
|
|
||||||
float32_t bbox_min_x;
|
|
||||||
float32_t bbox_max_x;
|
|
||||||
float32_t bbox_min_y;
|
|
||||||
float32_t bbox_max_y;
|
|
||||||
bool tlBorder[3];
|
|
||||||
float32_t area;
|
|
||||||
ifloat3_t edgesDX, edgesDY;
|
|
||||||
};
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
enum { TILE_WIDTH_IN_PIXELS = 64, COARSE_BLOCK_WIDTH_IN_PIXELS = 16, FINE_BLOCK_WIDTH_IN_PIXELS = 4 };
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
void _drawTriangle_Fine(int32_t tile_id, int32_t coarse_id, int32_t fine_id,
|
|
||||||
const DrawTriangleParam& param, const ifloat3_t& edges0, uint32_t testEdgeMask,
|
|
||||||
Rasterizer::DrawTriangleCallback callback)
|
|
||||||
{
|
|
||||||
ifloat3_t pixelEdges(edges0);
|
|
||||||
|
|
||||||
const fVector2 v0(param.verts[0]), v1(param.verts[1]), v2(param.verts[2]);
|
|
||||||
const bool edgeMask[3] = { (testEdgeMask & 1) != 0 , (testEdgeMask & 2) != 0 , (testEdgeMask & 4) != 0 };
|
|
||||||
|
|
||||||
int32_t fine_start_x = (tile_id % param.widthInTiles) * TILE_WIDTH_IN_PIXELS
|
|
||||||
+ (coarse_id % 4) * COARSE_BLOCK_WIDTH_IN_PIXELS + (fine_id % 4) * FINE_BLOCK_WIDTH_IN_PIXELS;
|
|
||||||
|
|
||||||
int32_t fine_start_y = (tile_id / param.widthInTiles) * TILE_WIDTH_IN_PIXELS
|
|
||||||
+ (coarse_id / 4) * COARSE_BLOCK_WIDTH_IN_PIXELS + (fine_id / 4)*FINE_BLOCK_WIDTH_IN_PIXELS;
|
|
||||||
|
|
||||||
for (int32_t y_index=0, y= fine_start_y; y_index < 4; y_index++, y++)
|
|
||||||
{
|
|
||||||
ifloat3_t edgesRow(pixelEdges);
|
|
||||||
|
|
||||||
for (int32_t x_index = 0, x=fine_start_x; x_index < 4; x_index++, x++)
|
|
||||||
{
|
|
||||||
bool rejected =
|
|
||||||
(edgeMask[0] && (edgesRow.x < 0 || (!param.tlBorder[0] && edgesRow.x == 0))) ||
|
|
||||||
(edgeMask[1] && (edgesRow.y < 0 || (!param.tlBorder[1] && edgesRow.y == 0))) ||
|
|
||||||
(edgeMask[2] && (edgesRow.z < 0 || (!param.tlBorder[2] && edgesRow.z == 0)));
|
|
||||||
|
|
||||||
if (!rejected)
|
|
||||||
{
|
|
||||||
fVector2 pixel(x + 0.5f, y + 0.5f);
|
|
||||||
|
|
||||||
float32_t w0 = (v2 - v1).crossProduct(pixel - v2);
|
|
||||||
float32_t w1 = (v0 - v2).crossProduct(pixel - v0);
|
|
||||||
float32_t w2 = (v1 - v0).crossProduct(pixel - v1);
|
|
||||||
|
|
||||||
fVector3 t = fVector3(w0 / param.area, (param.ccw ? w1 : w2) / param.area, (param.ccw ? w2 : w1) / param.area);
|
|
||||||
|
|
||||||
callback(std::make_pair(x, y), t);
|
|
||||||
}
|
|
||||||
edgesRow.sub(param.edgesDY);
|
|
||||||
}
|
|
||||||
pixelEdges.add(param.edgesDX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
void _drawTriangle_Coarse(int32_t tile_id, int32_t coarse_id,
|
|
||||||
DrawTriangleParam& param, const ifloat3_t& edges0, uint32_t testEdgeMask,
|
|
||||||
Rasterizer::DrawTriangleCallback callback)
|
|
||||||
{
|
|
||||||
const ifloat3_t blockEdgesDX(
|
|
||||||
param.edgesDX.x * FINE_BLOCK_WIDTH_IN_PIXELS,
|
|
||||||
param.edgesDX.y * FINE_BLOCK_WIDTH_IN_PIXELS,
|
|
||||||
param.edgesDX.z * FINE_BLOCK_WIDTH_IN_PIXELS
|
|
||||||
);
|
|
||||||
const ifloat3_t blockEdgesDY(
|
|
||||||
param.edgesDY.x * FINE_BLOCK_WIDTH_IN_PIXELS,
|
|
||||||
param.edgesDY.y * FINE_BLOCK_WIDTH_IN_PIXELS,
|
|
||||||
param.edgesDY.z * FINE_BLOCK_WIDTH_IN_PIXELS
|
|
||||||
);
|
|
||||||
const bool edgeMask[3] = { (testEdgeMask & 1) != 0 , (testEdgeMask & 2) != 0 , (testEdgeMask & 4) != 0 };
|
|
||||||
|
|
||||||
ifloat3_t blockReject(edges0);
|
|
||||||
ifloat3_t blockAccept(edges0);
|
|
||||||
ifloat3_t blockEdges(edges0);
|
|
||||||
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
if (blockEdgesDX[v] > 0) blockReject[v] += blockEdgesDX[v];
|
|
||||||
else if (blockEdgesDX[v] < 0) blockAccept[v] += blockEdgesDX[v];
|
|
||||||
|
|
||||||
if (blockEdgesDY[v] > 0) blockAccept[v] -= blockEdgesDY[v];
|
|
||||||
else if (blockEdgesDY[v] < 0) blockReject[v] -= blockEdgesDY[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t block_start_x = (tile_id % param.widthInTiles) * TILE_WIDTH_IN_PIXELS + (coarse_id % 4) * COARSE_BLOCK_WIDTH_IN_PIXELS;
|
|
||||||
int32_t block_start_y = (tile_id / param.widthInTiles) * TILE_WIDTH_IN_PIXELS + (coarse_id / 4) * COARSE_BLOCK_WIDTH_IN_PIXELS;
|
|
||||||
|
|
||||||
for (int32_t y_index = 0; y_index < 4; y_index++)
|
|
||||||
{
|
|
||||||
if (block_start_y + y_index * FINE_BLOCK_WIDTH_IN_PIXELS > param.bbox_max_y)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (block_start_y + (y_index + 1)*FINE_BLOCK_WIDTH_IN_PIXELS >= param.bbox_min_y)
|
|
||||||
{
|
|
||||||
ifloat3_t edgesRow(blockEdges);
|
|
||||||
ifloat3_t edgesRowReject, edgesRowAccept;
|
|
||||||
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
edgesRowReject[v] = blockReject[v];
|
|
||||||
edgesRowAccept[v] = blockAccept[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int32_t x_index = 0; x_index < 4; x_index++)
|
|
||||||
{
|
|
||||||
if (block_start_x + x_index * FINE_BLOCK_WIDTH_IN_PIXELS > param.bbox_max_x) break;
|
|
||||||
if (block_start_x + (x_index + 1)*FINE_BLOCK_WIDTH_IN_PIXELS >= param.bbox_min_x)
|
|
||||||
{
|
|
||||||
bool rejected =
|
|
||||||
(edgeMask[0] && (edgesRowReject[0] < 0 || (!param.tlBorder[0] && edgesRowReject[0] == 0))) ||
|
|
||||||
(edgeMask[1] && (edgesRowReject[1] < 0 || (!param.tlBorder[1] && edgesRowReject[1] == 0))) ||
|
|
||||||
(edgeMask[2] && (edgesRowReject[2] < 0 || (!param.tlBorder[2] && edgesRowReject[2] == 0)));
|
|
||||||
|
|
||||||
if (!rejected)
|
|
||||||
{
|
|
||||||
uint32_t newTestEdgeMask = testEdgeMask;
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
if (edgesRowAccept[v] > 0 || (edgesRowAccept[v] == 0 && param.tlBorder[v]))
|
|
||||||
{
|
|
||||||
newTestEdgeMask &= ~(1 << v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_drawTriangle_Fine(tile_id, coarse_id, y_index * 4 + x_index, param, edgesRow, newTestEdgeMask, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
edgesRow.sub(blockEdgesDY);
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
edgesRowReject[v] -= blockEdgesDY[v];
|
|
||||||
edgesRowAccept[v] -= blockEdgesDY[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blockEdges.add(blockEdgesDX);
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
blockReject[v] += blockEdgesDX[v];
|
|
||||||
blockAccept[v] += blockEdgesDX[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
void _drawTriangle_Title(int32_t tile_id,
|
|
||||||
DrawTriangleParam& param, const ifloat3_t& edges0, uint32_t testEdgeMask,
|
|
||||||
Rasterizer::DrawTriangleCallback callback)
|
|
||||||
{
|
|
||||||
const ifloat3_t blockEdgesDX(
|
|
||||||
param.edgesDX[0] * COARSE_BLOCK_WIDTH_IN_PIXELS,
|
|
||||||
param.edgesDX[1] * COARSE_BLOCK_WIDTH_IN_PIXELS,
|
|
||||||
param.edgesDX[2] * COARSE_BLOCK_WIDTH_IN_PIXELS
|
|
||||||
);
|
|
||||||
|
|
||||||
const ifloat3_t blockEdgesDY(
|
|
||||||
param.edgesDY[0] * COARSE_BLOCK_WIDTH_IN_PIXELS,
|
|
||||||
param.edgesDY[1] * COARSE_BLOCK_WIDTH_IN_PIXELS,
|
|
||||||
param.edgesDY[2] * COARSE_BLOCK_WIDTH_IN_PIXELS
|
|
||||||
);
|
|
||||||
const bool edgeMask[3] = { (testEdgeMask & 1) != 0 , (testEdgeMask & 2) != 0 , (testEdgeMask & 4) != 0 };
|
|
||||||
|
|
||||||
ifloat3_t blockReject(edges0);
|
|
||||||
ifloat3_t blockAccept(edges0);
|
|
||||||
ifloat3_t blockEdges(edges0);
|
|
||||||
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
if (blockEdgesDX[v] > 0) blockReject[v] += blockEdgesDX[v];
|
|
||||||
else if (blockEdgesDX[v] < 0) blockAccept[v] += blockEdgesDX[v];
|
|
||||||
|
|
||||||
if (blockEdgesDY[v] > 0) blockAccept[v] -= blockEdgesDY[v];
|
|
||||||
else if (blockEdgesDY[v] < 0) blockReject[v] -= blockEdgesDY[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t block_start_x = (tile_id % param.widthInTiles) * TILE_WIDTH_IN_PIXELS;
|
|
||||||
int32_t block_start_y = (tile_id / param.widthInTiles) * TILE_WIDTH_IN_PIXELS;
|
|
||||||
|
|
||||||
for (int32_t y_index = 0; y_index < 4; y_index++)
|
|
||||||
{
|
|
||||||
if (block_start_y + y_index * COARSE_BLOCK_WIDTH_IN_PIXELS > param.bbox_max_y)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (block_start_y + (y_index + 1)*COARSE_BLOCK_WIDTH_IN_PIXELS >= param.bbox_min_y)
|
|
||||||
{
|
|
||||||
ifloat3_t edges(blockEdges);
|
|
||||||
ifloat3_t edgesRowReject, edgesRowAccept;
|
|
||||||
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
edgesRowReject[v] = blockReject[v];
|
|
||||||
edgesRowAccept[v] = blockAccept[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t x_index = 0; x_index < 4; x_index++)
|
|
||||||
{
|
|
||||||
if (block_start_x + x_index * COARSE_BLOCK_WIDTH_IN_PIXELS > param.bbox_max_x)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (block_start_x + (x_index + 1)*COARSE_BLOCK_WIDTH_IN_PIXELS >= param.bbox_min_x)
|
|
||||||
{
|
|
||||||
bool rejected =
|
|
||||||
(edgeMask[0] && (edgesRowReject[0] < 0 || (!param.tlBorder[0] && edgesRowReject[0] == 0))) ||
|
|
||||||
(edgeMask[1] && (edgesRowReject[1] < 0 || (!param.tlBorder[1] && edgesRowReject[1] == 0))) ||
|
|
||||||
(edgeMask[2] && (edgesRowReject[2] < 0 || (!param.tlBorder[2] && edgesRowReject[2] == 0)));
|
|
||||||
|
|
||||||
if (!rejected)
|
|
||||||
{
|
|
||||||
uint32_t newTestEdgeMask = testEdgeMask;
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
if (edgesRowAccept[v] > 0 || (edgesRowAccept[v] == 0 && param.tlBorder[v]))
|
|
||||||
{
|
|
||||||
newTestEdgeMask &= ~(1 << v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_drawTriangle_Coarse(tile_id, y_index * 4 + x_index, param, edges, newTestEdgeMask, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
edges.sub(blockEdgesDY);
|
|
||||||
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
edgesRowReject[v] -= blockEdgesDY[v];
|
|
||||||
edgesRowAccept[v] -= blockEdgesDY[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blockEdges.add(blockEdgesDX);
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (edgeMask[v])
|
|
||||||
{
|
|
||||||
blockReject[v] += blockEdgesDX[v];
|
|
||||||
blockAccept[v] += blockEdgesDX[v];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
void Rasterizer::drawTriangleLarrabee(int32_t canvasWidth, int32_t canvasHeight,
|
|
||||||
const fVector2& v0, const fVector2& v1, const fVector2& v2,
|
|
||||||
DrawTriangleCallback callback, bool ccw)
|
|
||||||
{
|
|
||||||
assert(canvasWidth >= TILE_WIDTH_IN_PIXELS && canvasHeight >= TILE_WIDTH_IN_PIXELS);
|
|
||||||
assert(canvasWidth%TILE_WIDTH_IN_PIXELS == 0 && canvasHeight%TILE_WIDTH_IN_PIXELS == 0);
|
|
||||||
|
|
||||||
DrawTriangleParam param;
|
|
||||||
param.widthInTiles = canvasWidth / TILE_WIDTH_IN_PIXELS;
|
|
||||||
|
|
||||||
//ccw
|
|
||||||
bool isCCW = (v1 - v0).crossProduct(v2 - v1)>0;
|
|
||||||
if (isCCW != ccw) return;
|
|
||||||
|
|
||||||
param.ccw = ccw;
|
|
||||||
param.verts[0] = v0;
|
|
||||||
param.verts[1] = ccw ? v1 : v2;
|
|
||||||
param.verts[2] = ccw ? v2 : v1;
|
|
||||||
param.area = (param.verts[1] - param.verts[0]).crossProduct(param.verts[2] - param.verts[1]);
|
|
||||||
|
|
||||||
ifloat2_t vertices[3];
|
|
||||||
for (size_t i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
vertices[i] = ifloat2_t(param.verts[i].x, param.verts[i].y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//get window coordinates bounding box
|
|
||||||
param.bbox_min_x = MathUtil::min3(v0.x, v1.x, v2.x);
|
|
||||||
param.bbox_max_x = MathUtil::max3(v0.x, v1.x, v2.x);
|
|
||||||
param.bbox_min_y = MathUtil::min3(v0.y, v1.y, v2.y);
|
|
||||||
param.bbox_max_y = MathUtil::max3(v0.y, v1.y, v2.y);
|
|
||||||
|
|
||||||
//canvas size
|
|
||||||
ifloat_t iCanvasWidth = ifloat_init(canvasWidth);
|
|
||||||
ifloat_t iCanvasHeight = ifloat_init(canvasHeight);
|
|
||||||
|
|
||||||
// clip triangles that are fully outside the scissor rect (scissor rect = whole window)
|
|
||||||
if (param.bbox_max_x < 0 || param.bbox_max_y < 0 || param.bbox_min_x >= canvasWidth || param.bbox_min_y >= canvasHeight)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (param.bbox_min_x < 0) param.bbox_min_x = 0;
|
|
||||||
if (param.bbox_min_y < 0) param.bbox_min_y = 0;
|
|
||||||
if (param.bbox_max_x > canvasWidth - 1.f) param.bbox_max_x = canvasWidth - 1.f;
|
|
||||||
if (param.bbox_max_y > canvasHeight - 1.f) param.bbox_max_y = canvasHeight - 1.f;
|
|
||||||
|
|
||||||
// tile range
|
|
||||||
int32_t first_tile_x = (int32_t)(param.bbox_min_x / TILE_WIDTH_IN_PIXELS);
|
|
||||||
int32_t first_tile_y = (int32_t)(param.bbox_min_y / TILE_WIDTH_IN_PIXELS);
|
|
||||||
int32_t last_tile_x = (int32_t)(param.bbox_max_x / TILE_WIDTH_IN_PIXELS);
|
|
||||||
int32_t last_tile_y = (int32_t)(param.bbox_max_y / TILE_WIDTH_IN_PIXELS);
|
|
||||||
|
|
||||||
// evaluate edge equation at the top left tile
|
|
||||||
ifloat_t firstTileX = first_tile_x * ifloat_init(TILE_WIDTH_IN_PIXELS);
|
|
||||||
ifloat_t firstTileY = first_tile_y * ifloat_init(TILE_WIDTH_IN_PIXELS);
|
|
||||||
|
|
||||||
ifloat3_t edges0;
|
|
||||||
ifloat3_t tileEdgesDX, tileEdgesDY, edgesReject, edgesAccept;
|
|
||||||
const ifloat_t kZeroPointFive = ifloat_init(0.5f);
|
|
||||||
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
size_t v_end = (v + 1) % 3;
|
|
||||||
param.edgesDX[v] = vertices[v_end].x - vertices[v].x;
|
|
||||||
param.edgesDY[v] = vertices[v_end].y - vertices[v].y;
|
|
||||||
|
|
||||||
tileEdgesDX[v] = param.edgesDX[v] * TILE_WIDTH_IN_PIXELS;
|
|
||||||
tileEdgesDY[v] = param.edgesDY[v] * TILE_WIDTH_IN_PIXELS;
|
|
||||||
|
|
||||||
//(V0,V1) X (V0, P) = (x1-x0)(py-y0)-(y1-y0)(px-x0)
|
|
||||||
edges0[v] = ifloat_multiply(param.edgesDX[v], (firstTileY + kZeroPointFive - vertices[v].y))
|
|
||||||
- ifloat_multiply(param.edgesDY[v], (firstTileX + kZeroPointFive - vertices[v].x));
|
|
||||||
|
|
||||||
// Top-left rule:
|
|
||||||
// shift top-left edges ever so slightly outward to make the top-left edges be
|
|
||||||
// the tie-breakers when rasterizing adjacent triangles
|
|
||||||
if ((vertices[v_end].y == vertices[v].y && vertices[v_end].x < vertices[v].x) ||
|
|
||||||
vertices[v_end].y < vertices[v].y)
|
|
||||||
{
|
|
||||||
param.tlBorder[v] = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
param.tlBorder[v] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
edgesReject[v] = edgesAccept[v] = edges0[v];
|
|
||||||
|
|
||||||
if (tileEdgesDX[v] > 0) edgesReject[v] += tileEdgesDX[v];
|
|
||||||
else if (tileEdgesDX[v] < 0) edgesAccept[v] += tileEdgesDX[v];
|
|
||||||
|
|
||||||
if (tileEdgesDY[v] > 0) edgesAccept[v] -= tileEdgesDY[v];
|
|
||||||
else if (tileEdgesDY[v] < 0) edgesReject[v] -= tileEdgesDY[v];
|
|
||||||
}
|
|
||||||
|
|
||||||
ifloat3_t rowEdges(edges0);
|
|
||||||
|
|
||||||
int32_t tile_row_start = first_tile_y * param.widthInTiles + first_tile_x;
|
|
||||||
for (int32_t tile_y = first_tile_y; tile_y <= last_tile_y; tile_y++)
|
|
||||||
{
|
|
||||||
ifloat3_t edges(rowEdges);
|
|
||||||
ifloat3_t tileEdgesReject(edgesReject);
|
|
||||||
ifloat3_t tileEdgesAccept(edgesAccept);
|
|
||||||
|
|
||||||
int32_t tile_i = tile_row_start;
|
|
||||||
for (int32_t tile_x = first_tile_x; tile_x <= last_tile_x; tile_x++)
|
|
||||||
{
|
|
||||||
bool rejected =
|
|
||||||
((tileEdgesReject[0] < 0 || (!param.tlBorder[0] && tileEdgesReject[0] == 0))) ||
|
|
||||||
((tileEdgesReject[1] < 0 || (!param.tlBorder[1] && tileEdgesReject[1] == 0))) ||
|
|
||||||
((tileEdgesReject[2] < 0 || (!param.tlBorder[2] && tileEdgesReject[2] == 0)));
|
|
||||||
|
|
||||||
if (!rejected)
|
|
||||||
{
|
|
||||||
//draw title
|
|
||||||
uint32_t testEdgeMask = 0;
|
|
||||||
for (size_t v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
if (tileEdgesAccept[v] < 0 || (tileEdgesAccept[v] == 0 && !param.tlBorder[v]))
|
|
||||||
{
|
|
||||||
testEdgeMask += (1 << v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_drawTriangle_Title(tile_i, param, edges, testEdgeMask, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
//x setp
|
|
||||||
edges.sub(tileEdgesDY);
|
|
||||||
tileEdgesReject.sub(tileEdgesDY);
|
|
||||||
tileEdgesAccept.sub(tileEdgesDY);
|
|
||||||
tile_i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//y step
|
|
||||||
rowEdges.add(tileEdgesDX);
|
|
||||||
edgesReject.add(tileEdgesDX);
|
|
||||||
edgesAccept.add(tileEdgesDX);
|
|
||||||
tile_row_start += param.widthInTiles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
|
||||||
void Rasterizer::drawTriangleScanline(int32_t canvasWidth, int32_t canvasHeight, const fVector3& v0, const fVector3& v1, const fVector3& v2, DrawTriangleCallback callback)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
//back cull
|
|
||||||
fVector3 edge0 = v2 - v1;
|
|
||||||
fVector3 edge1 = v0 - v2;
|
|
||||||
fVector3 vnormal = edge0.crossProduct(edge1);
|
|
||||||
if (vnormal.z > 0) return;
|
|
||||||
|
|
||||||
fVector3 edge2 = v1 - v0;
|
|
||||||
|
|
||||||
float xmin = MathUtil::min3(v0.x, v1.x, v2.x);
|
|
||||||
float ymin = MathUtil::min3(v0.y, v1.y, v2.y);
|
|
||||||
float xmax = MathUtil::max3(v0.x, v1.x, v2.x);
|
|
||||||
float ymax = MathUtil::max3(v0.y, v1.y, v2.y);
|
|
||||||
|
|
||||||
float area = _edge(v0, v1, v2);
|
|
||||||
|
|
||||||
int32_t x0 = MathUtil::max2(0, (int32_t)std::floor(xmin));
|
|
||||||
int32_t x1 = MathUtil::min2(canvasWidth - 1, (int32_t)std::floor(xmax));
|
|
||||||
int32_t y0 = MathUtil::max2(0, (int32_t)std::floor(ymin));
|
|
||||||
int32_t y1 = MathUtil::min2(canvasHeight - 1, (int32_t)std::floor(ymax));
|
|
||||||
|
|
||||||
for (int32_t y = y0; y <= y1; y++) {
|
|
||||||
for (int32_t x = x0; x <= x1; x++) {
|
|
||||||
|
|
||||||
fVector3 pixel(x + 0.5f, y + 0.5f, 0.f);
|
|
||||||
|
|
||||||
bool overlaps = true;
|
|
||||||
|
|
||||||
float w0 = _edge(v1, v2, pixel);
|
|
||||||
overlaps &= (w0 == 0 ? ((edge0.y == 0 && edge0.x > 0) || edge0.y > 0) : (w0 > 0));
|
|
||||||
if (!overlaps) continue;
|
|
||||||
|
|
||||||
float w1 = _edge(v2, v0, pixel);
|
|
||||||
overlaps &= (w1 == 0 ? ((edge1.y == 0 && edge1.x > 0) || edge1.y > 0) : (w1 > 0));
|
|
||||||
if (!overlaps) continue;
|
|
||||||
|
|
||||||
float w2 = _edge(v0, v1, pixel);
|
|
||||||
overlaps &= (w2 == 0 ? ((edge2.y == 0 && edge2.x > 0) || edge2.y > 0) : (w2 > 0));
|
|
||||||
if (!overlaps) continue;
|
|
||||||
|
|
||||||
|
|
||||||
fVector3 t = fVector3(w0 / area, w1 / area, w2 / area);
|
|
||||||
|
|
||||||
float invZ = MathUtil::lerp3(v0.z, v1.z, v2.z, t);
|
|
||||||
t *= fVector3(v0.z / invZ, v1.z / invZ, v2.z / invZ);
|
|
||||||
|
|
||||||
callback(std::make_pair(x, y), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
#include "scene/dvc_scene_node.h"
|
||||||
|
#include "pipe/dvc_render_step0_input_assember.h"
|
||||||
|
#include "pipe/dvc_render_step1_vertex_shader.h"
|
||||||
|
#include "pipe/dvc_render_step2_rasterizer.h"
|
||||||
|
#include "pipe/dvc_render_step3_output_merge.h"
|
||||||
|
#include "scene/component/dvc_camera_component.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
RenderPipe::RenderPipe(Device& device)
|
||||||
|
: m_device(device)
|
||||||
|
, m_aaTech(AntiAliasingTech::AA_None)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderPipe::~RenderPipe()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPipe::pushRenderable(RenderableConstPtr renderable)
|
||||||
|
{
|
||||||
|
m_renderableQueue.push_back(renderable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPipe::process(RenderTarget& renderTarget)
|
||||||
|
{
|
||||||
|
//Assembere input
|
||||||
|
InputAssemberStep IA;
|
||||||
|
IA.process(m_renderableQueue);
|
||||||
|
|
||||||
|
//Vertex shader
|
||||||
|
VertexShaderStep VS;
|
||||||
|
VS.process(*this, IA.m_nodes);
|
||||||
|
|
||||||
|
//Pixel shader
|
||||||
|
RasterizerStep rasterizerStep;
|
||||||
|
rasterizerStep.process(*this, VS.m_nodes, m_aaTech, renderTarget.getWidth(), renderTarget.getHeight());
|
||||||
|
|
||||||
|
//Output Merge
|
||||||
|
OutputMergerStep OM;
|
||||||
|
OM.process(rasterizerStep.m_startOffsetArray, rasterizerStep.m_fragementArray, m_aaTech, renderTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#include "pipe/dvc_render_queue.h"
|
|
||||||
#include "scene/dvc_scene_node.h"
|
|
||||||
#include "pipe/dvc_render_step_IA.h"
|
|
||||||
#include "pipe/dvc_render_step_VS.h"
|
|
||||||
#include "pipe/dvc_render_step_PS.h"
|
|
||||||
#include "scene/component/dvc_camera_component.h"
|
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
RenderQueue::RenderQueue()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderQueue::~RenderQueue()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderQueue::pushRenderable(RenderableConstPtr renderable)
|
|
||||||
{
|
|
||||||
m_queue.push_back(renderable);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderableConstPtr RenderQueue::getRenderable(size_t index) const
|
|
||||||
{
|
|
||||||
assert(index < m_queue.size());
|
|
||||||
if (index < m_queue.size())
|
|
||||||
{
|
|
||||||
return m_queue[index];
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderQueue::build(const Scene& scene)
|
|
||||||
{
|
|
||||||
//Build render queue
|
|
||||||
scene.getRootSceneNode()->buildRenderQueue(fMatrix4::IDENTITY, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderQueue::process(UniformBuffer& uniformBuffer, RenderTarget& renderTarget)
|
|
||||||
{
|
|
||||||
//Assembere input
|
|
||||||
InputAssemberStep IA;
|
|
||||||
IA.process(*this);
|
|
||||||
|
|
||||||
//Vertex shader
|
|
||||||
VertexShaderStep VS;
|
|
||||||
VS.process(uniformBuffer, IA.getNodes());
|
|
||||||
|
|
||||||
//Pixel shader
|
|
||||||
PixelShaderStep PS;
|
|
||||||
PS.process(VS.getNodes(), renderTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
|
||||||
+4
-4
@@ -1,14 +1,14 @@
|
|||||||
#include "pipe/dvc_render_step_IA.h"
|
#include "pipe/dvc_render_step0_input_assember.h"
|
||||||
#include "pipe/dvc_renderable.h"
|
#include "pipe/dvc_renderable.h"
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
void InputAssemberStep::process(const RenderQueue& renderQueue)
|
void InputAssemberStep::process(const RenderableArray& renderableArray)
|
||||||
{
|
{
|
||||||
size_t counts = renderQueue.getRenderableCounts();
|
size_t counts = renderableArray.size();
|
||||||
for (size_t i = 0; i < counts; i++)
|
for (size_t i = 0; i < counts; i++)
|
||||||
{
|
{
|
||||||
RenderableConstPtr renderable = renderQueue.getRenderable(i);
|
RenderableConstPtr renderable = renderableArray[i];
|
||||||
if (renderable)
|
if (renderable)
|
||||||
{
|
{
|
||||||
Node node;
|
Node node;
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#include "pipe/dvc_render_step1_vertex_shader.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
#include "device/dvc_buffer_accessor.h"
|
||||||
|
#include "math/dvc_math_util.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
void VertexShaderStep::process(RenderPipe& pipe, const InputAssemberStep::NodeArray& assembedNodeArray)
|
||||||
|
{
|
||||||
|
Device& device = pipe.getDevice();
|
||||||
|
UniformBuffer& uniformBuffer = pipe.getUniformBuffer();
|
||||||
|
|
||||||
|
const fVector3* eyePos = (const fVector3*)(uniformBuffer.getAttribute("camera:eye_pos"));
|
||||||
|
const fMatrix4* cameraView = (const fMatrix4*)(uniformBuffer.getAttribute("camera:view_mat"));
|
||||||
|
float32_t cameraNear = *((const float32_t*)(uniformBuffer.getAttribute("camera:near")));
|
||||||
|
float32_t cameraFar = *((const float32_t*)(uniformBuffer.getAttribute("camera:far")));
|
||||||
|
|
||||||
|
//int debug_index = 0;
|
||||||
|
InputAssemberStep::NodeArray::const_iterator it, end = assembedNodeArray.end();
|
||||||
|
for (it = assembedNodeArray.begin(); it != end; ++it)
|
||||||
|
{
|
||||||
|
const InputAssemberStep::Node& inputNode = *it;
|
||||||
|
|
||||||
|
//update self uniform value
|
||||||
|
uniformBuffer.setAttribute("self:world_transform", inputNode.transform);
|
||||||
|
|
||||||
|
fMatrix4 worldInverseTrans = inputNode.transform.inverse().transpose();
|
||||||
|
uniformBuffer.setAttribute("self:world_transform_inverse_trans", worldInverseTrans);
|
||||||
|
|
||||||
|
VertexShaderInterface* vs = pipe.getDebugMaterial() ? pipe.getDebugMaterial()->getVertexShader(): inputNode.material->getVertexShader();
|
||||||
|
vs->begin(&pipe,
|
||||||
|
[inputNode](VertexElementType type) -> DeviceBufferAccessorConstPtr
|
||||||
|
{
|
||||||
|
InputAssemberStep::PrimitiveAttributes::const_iterator it = inputNode.vertexData.find(type);
|
||||||
|
if (it != inputNode.vertexData.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
size_t vertexCounts = inputNode.indices->getCount();
|
||||||
|
size_t outputVertexByteSize = vs->getOutputVertexDesc().vertexByteSize();
|
||||||
|
|
||||||
|
Node outputNode;
|
||||||
|
outputNode.material = inputNode.material;
|
||||||
|
outputNode.vertexCounts = vertexCounts;
|
||||||
|
outputNode.vertexDesc = vs->getOutputVertexDesc();
|
||||||
|
outputNode.vertexBuf = device.newDeviceBuffer(outputVertexByteSize * vertexCounts);
|
||||||
|
outputNode.depth.resize(vertexCounts);
|
||||||
|
outputNode.invZ.resize(vertexCounts);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < vertexCounts; i++)
|
||||||
|
{
|
||||||
|
uint16_t index = *((const uint16_t*)(inputNode.indices->getElement(i)));
|
||||||
|
|
||||||
|
uint8_t* outputVertexMemory = (uint8_t*)(outputNode.vertexBuf->ptr(i * outputVertexByteSize));
|
||||||
|
vs->process(index, (float32_t*)outputVertexMemory);
|
||||||
|
|
||||||
|
//TODO: clip
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: div-zero
|
||||||
|
|
||||||
|
size_t ndcPosOffset = outputNode.vertexDesc.getElementByType(VET_POSITION_NDC)->offset;
|
||||||
|
const fVector3* vertexNDCPos = (const fVector3*)(outputVertexMemory+ndcPosOffset);
|
||||||
|
|
||||||
|
outputNode.depth[i] = (std::fabsf(vertexNDCPos->z) - cameraNear) / (cameraFar - cameraNear);
|
||||||
|
float32_t cameraSpaceZ = vertexNDCPos->z;
|
||||||
|
outputNode.invZ[i] = 1.f/std::fabsf(vertexNDCPos->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nodes.push_back(outputNode);
|
||||||
|
|
||||||
|
vs->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
+41
-17
@@ -1,30 +1,44 @@
|
|||||||
#include "pipe/dvc_render_step_PS.h"
|
#include "pipe/dvc_render_step2_rasterizer.h"
|
||||||
#include "shader/dvc_shader_interface.h"
|
#include "shader/dvc_shader_interface.h"
|
||||||
#include "device/dvc_buffer.h"
|
#include "device/dvc_buffer.h"
|
||||||
#include "pipe/dvc_rasterizer.h"
|
#include "rasterizer/dvc_rasterizer_triangle.h"
|
||||||
#include "math/dvc_math_util.h"
|
#include "math/dvc_math_util.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
#include "asset/dvc_texture.h"
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
void PixelShaderStep::process(const VertexShaderStep::NodeArray& vsNodeArray, RenderTarget& renderTarget)
|
void RasterizerStep::process(RenderPipe& pipe, const VertexShaderStep::NodeArray& vsNodeArray, AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight)
|
||||||
{
|
{
|
||||||
ShaderFileInterface* shaderInterface = davinci::LoadShaderFile("TestShader.dll");
|
Device& device = pipe.getDevice();
|
||||||
PixelShaderInterface* pixelShader = shaderInterface->getPixelShader("xxx");
|
UniformBuffer& uniformBuffer = pipe.getUniformBuffer();
|
||||||
|
|
||||||
int32_t targetWidth = renderTarget.getWidth();
|
|
||||||
int32_t targetHeight = renderTarget.getHeight();
|
|
||||||
|
|
||||||
fMatrix4 view_trans =
|
fMatrix4 view_trans =
|
||||||
fMatrix4::makeTrans(targetWidth / 2.f, targetHeight / 2.f, 0.f) *
|
fMatrix4::makeTrans(canvasWidth / 2.f, canvasHeight / 2.f, 0.f) *
|
||||||
fMatrix4::makeScale(targetWidth / 2.f, targetHeight / 2.f, 1.f);
|
fMatrix4::makeScale(canvasWidth / 2.f, canvasHeight / 2.f, 1.f);
|
||||||
|
|
||||||
|
m_startOffsetArray.resize(canvasWidth* canvasHeight, -1);
|
||||||
|
|
||||||
|
MaterialPtr debugMaterial = pipe.getDebugMaterial();
|
||||||
|
|
||||||
VertexShaderStep::NodeArray::const_iterator it, end = vsNodeArray.end();
|
VertexShaderStep::NodeArray::const_iterator it, end = vsNodeArray.end();
|
||||||
for (it = vsNodeArray.begin(); it != end; ++it)
|
for (it = vsNodeArray.begin(); it != end; ++it)
|
||||||
{
|
{
|
||||||
const VertexShaderStep::Node& node = *it;
|
const VertexShaderStep::Node& node = *it;
|
||||||
|
|
||||||
|
if (debugMaterial)
|
||||||
|
{
|
||||||
|
debugMaterial->pickupParam(node.material);
|
||||||
|
}
|
||||||
|
FragementShaderInterface* fragementShader = debugMaterial ? debugMaterial->getFragementShader() : node.material->getFragementShader();
|
||||||
|
if (!(fragementShader->begin(&pipe, debugMaterial ? debugMaterial : node.material, node.vertexDesc)))
|
||||||
|
{
|
||||||
|
//TODO: shader fallback
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
size_t vertexSize = node.vertexDesc.vertexByteSize();
|
size_t vertexSize = node.vertexDesc.vertexByteSize();
|
||||||
size_t POS_offset = node.vertexDesc.getElement(VET_POSITION)->offset;
|
size_t POS_offset = node.vertexDesc.getElementByType(VET_POSITION_NDC)->offset;
|
||||||
|
|
||||||
for (size_t i = 0; i < node.vertexCounts; i += 3)
|
for (size_t i = 0; i < node.vertexCounts; i += 3)
|
||||||
{
|
{
|
||||||
@@ -39,9 +53,10 @@ void PixelShaderStep::process(const VertexShaderStep::NodeArray& vsNodeArray, Re
|
|||||||
std::vector<float32_t> invZ = { node.invZ[i + 0], node.invZ[i + 1], node.invZ[i + 2] };
|
std::vector<float32_t> invZ = { node.invZ[i + 0], node.invZ[i + 1], node.invZ[i + 2] };
|
||||||
std::vector<float32_t> vertexDepth = { node.depth[i+0], node.depth[i + 1], node.depth[i + 2]};
|
std::vector<float32_t> vertexDepth = { node.depth[i+0], node.depth[i + 1], node.depth[i + 2]};
|
||||||
|
|
||||||
Rasterizer::drawTriangleLarrabee(targetWidth, targetHeight, pos0.xy(), pos1.xy(), pos2.xy(),
|
Rasterizer::drawTriangleLarrabee(aaTech,
|
||||||
[pixelShader, vertex0, vertex1, vertex2, invZ, vertexDepth, &node, &renderTarget]
|
canvasWidth, canvasHeight, pos0.xy(), pos1.xy(), pos2.xy(),
|
||||||
(const std::pair<int32_t, int32_t>& dot, const fVector3& percent)
|
[this, canvasWidth, fragementShader, vertex0, vertex1, vertex2, invZ, vertexDepth, &node]
|
||||||
|
(const std::pair<int32_t, int32_t>& dot, const fVector3& percent, uint32_t mask)
|
||||||
{
|
{
|
||||||
fVector3 percentCorrected(percent);
|
fVector3 percentCorrected(percent);
|
||||||
|
|
||||||
@@ -59,14 +74,23 @@ void PixelShaderStep::process(const VertexShaderStep::NodeArray& vsNodeArray, Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
fVector4 color;
|
fVector4 color;
|
||||||
pixelShader->process(node.vertexDesc, &(pixelData[0]), color);
|
fragementShader->process(pixelData.data(), color);
|
||||||
|
|
||||||
float32_t depth = MathUtil::lerp3(vertexDepth[0], vertexDepth[1], vertexDepth[2], percentCorrected);
|
float32_t depth = MathUtil::lerp3(vertexDepth[0], vertexDepth[1], vertexDepth[2], percentCorrected);
|
||||||
|
|
||||||
int32_t x = dot.first;
|
int32_t x = dot.first;
|
||||||
int32_t y = dot.second;
|
int32_t y = dot.second;
|
||||||
renderTarget.setPixel(x, y, color, depth);
|
int32_t currentOffset = m_startOffsetArray[x + y * canvasWidth];
|
||||||
}
|
|
||||||
|
m_startOffsetArray[x + y * canvasWidth] = (int32_t)(m_fragementArray.size());
|
||||||
|
|
||||||
|
Fragement newFragment;
|
||||||
|
newFragment.color = color;
|
||||||
|
newFragment.depth = depth;
|
||||||
|
newFragment.mask = mask;
|
||||||
|
newFragment.next = currentOffset;
|
||||||
|
this->m_fragementArray.push_back(newFragment);
|
||||||
|
},true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include "pipe/dvc_render_step3_output_merge.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
void OutputMergerStep::process(const RasterizerStep::StartOffsetArray& startOffsetArray, const RasterizerStep::FragementArray& fragementArray,
|
||||||
|
AntiAliasingTech aaTech, RenderTarget& renderTarget)
|
||||||
|
{
|
||||||
|
int32_t canvasWidth = renderTarget.getWidth();
|
||||||
|
int32_t canvasHeight = renderTarget.getHeight();
|
||||||
|
|
||||||
|
for (int32_t y = 0; y < canvasHeight; y++)
|
||||||
|
{
|
||||||
|
for (int32_t x = 0; x < canvasWidth; x++)
|
||||||
|
{
|
||||||
|
int32_t fragementID = startOffsetArray[y * canvasWidth + x];
|
||||||
|
std::multimap<float32_t, int32_t> fragementArrayMap;
|
||||||
|
|
||||||
|
while (fragementID >=0 && fragementID < (int32_t)fragementArray.size())
|
||||||
|
{
|
||||||
|
const RasterizerStep::Fragement& fragement = fragementArray[fragementID];
|
||||||
|
fragementArrayMap.insert(std::make_pair(-fragement.depth, fragementID));
|
||||||
|
fragementID = fragement.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aaTech == AntiAliasingTech::AA_None)
|
||||||
|
{
|
||||||
|
mergeFragement_without_AA(x, y, fragementArrayMap, fragementArray, renderTarget);
|
||||||
|
}
|
||||||
|
else if (aaTech == AntiAliasingTech::AA_MSAA_2X2)
|
||||||
|
{
|
||||||
|
mergeFragement_with_AA<4, 0xF>(x, y, fragementArrayMap, fragementArray, renderTarget);
|
||||||
|
}
|
||||||
|
else if (aaTech == AntiAliasingTech::AA_MSAA_4X4)
|
||||||
|
{
|
||||||
|
mergeFragement_with_AA<16, 0xFFFF>(x, y, fragementArrayMap, fragementArray, renderTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputMergerStep::mergeFragement_without_AA(int32_t x, int32_t y, const std::multimap<float32_t, int32_t>& fragementArrayMap,
|
||||||
|
const RasterizerStep::FragementArray& fragementArray, RenderTarget& renderTarget)
|
||||||
|
{
|
||||||
|
if (fragementArrayMap.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RasterizerStep::Fragement& firstFragement = fragementArray[fragementArrayMap.rbegin()->second];
|
||||||
|
renderTarget.setPixel(x, y, firstFragement.color, firstFragement.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#include "pipe/dvc_render_step_VS.h"
|
|
||||||
#include "shader/dvc_shader_interface.h"
|
|
||||||
#include "device/dvc_buffer_accessor.h"
|
|
||||||
#include "math/dvc_math_util.h"
|
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
void VertexShaderStep::process(UniformBuffer& uniformBuffer, const InputAssemberStep::NodeArray& assembedNodeArray)
|
|
||||||
{
|
|
||||||
ShaderFileInterface* shaderInterface = davinci::LoadShaderFile("TestShader.dll");
|
|
||||||
VertexShaderInterface* standardVS = shaderInterface->getVertexShader("xxxx");
|
|
||||||
|
|
||||||
const fVector3* eyePos = (const fVector3*)(uniformBuffer.getAttribute("camera:eye_pos"));
|
|
||||||
const fMatrix4* cameraView = (const fMatrix4*)(uniformBuffer.getAttribute("camera:view_mat"));
|
|
||||||
float32_t cameraNear = *((const float32_t*)(uniformBuffer.getAttribute("camera:near")));
|
|
||||||
float32_t cameraFar = *((const float32_t*)(uniformBuffer.getAttribute("camera:far")));
|
|
||||||
|
|
||||||
//int debug_index = 0;
|
|
||||||
InputAssemberStep::NodeArray::const_iterator it, end = assembedNodeArray.end();
|
|
||||||
for (it = assembedNodeArray.begin(); it != end; ++it)
|
|
||||||
{
|
|
||||||
const InputAssemberStep::Node& inputNode = *it;
|
|
||||||
|
|
||||||
//update self uniform value
|
|
||||||
uniformBuffer.setAttribute("self:world_transform", inputNode.transform);
|
|
||||||
|
|
||||||
standardVS->prepare(&uniformBuffer,
|
|
||||||
[inputNode](VertexElementType type) -> DeviceBufferAccessorConstPtr
|
|
||||||
{
|
|
||||||
InputAssemberStep::PrimitiveAttributes::const_iterator it = inputNode.vertexData.find(type);
|
|
||||||
if (it != inputNode.vertexData.end())
|
|
||||||
{
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
size_t vertexCounts = inputNode.indices->getCount();
|
|
||||||
|
|
||||||
Node outputNode;
|
|
||||||
outputNode.vertexCounts = vertexCounts;
|
|
||||||
outputNode.vertexDesc = standardVS->getOutputVertexDesc();
|
|
||||||
outputNode.vertexBuf = std::make_shared<DeviceBuffer>(outputNode.vertexDesc.vertexByteSize() * vertexCounts);
|
|
||||||
outputNode.depth.resize(vertexCounts);
|
|
||||||
outputNode.invZ.resize(vertexCounts);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < vertexCounts; i++)
|
|
||||||
{
|
|
||||||
size_t index = 0;
|
|
||||||
if (inputNode.indices->getComponentType() == CT_Uint16)
|
|
||||||
{
|
|
||||||
index = (size_t)(*(uint16_t*)(inputNode.indices->getElement(i)));
|
|
||||||
}
|
|
||||||
else if(inputNode.indices->getComponentType() == CT_Uint32)
|
|
||||||
{
|
|
||||||
index = (size_t)(*(uint32_t*)(inputNode.indices->getElement(i)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//error
|
|
||||||
}
|
|
||||||
|
|
||||||
fVector3 vertexWorldPos;
|
|
||||||
void* outputVertexMemory = outputNode.vertexBuf->ptr(i* outputNode.vertexDesc.vertexByteSize());
|
|
||||||
standardVS->process(index, outputVertexMemory, vertexWorldPos);
|
|
||||||
|
|
||||||
//TODO: clip
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: div-zero
|
|
||||||
fVector3 cameraSpacePos = (*cameraView) * vertexWorldPos;
|
|
||||||
outputNode.depth[i] = (std::fabsf(cameraSpacePos.z) - cameraNear) / (cameraFar - cameraNear);
|
|
||||||
|
|
||||||
float32_t cameraSpaceZ = cameraSpacePos.z;
|
|
||||||
outputNode.invZ[i] = 1.f/std::fabsf(cameraSpacePos.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_nodes.push_back(outputNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
|
||||||
@@ -15,6 +15,7 @@ bool RenderableEntity::buildAssemberNode(InputAssemberStep::Node& node) const
|
|||||||
node.transform = m_worldTransform;
|
node.transform = m_worldTransform;
|
||||||
node.vertexData = m_primitive->attributes;
|
node.vertexData = m_primitive->attributes;
|
||||||
node.indices = m_primitive->indices;
|
node.indices = m_primitive->indices;
|
||||||
|
node.material = m_primitive->material;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,615 @@
|
|||||||
|
#include "rasterizer/dvc_rasterizer_triangle.h"
|
||||||
|
#include "math/dvc_fix_point.h"
|
||||||
|
#include "math/dvc_math_util.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
/*
|
||||||
|
https://github.com/nlguillemot/vigilant-system
|
||||||
|
https://wiki.joak.org/public:cs:rasterization_on_larrabee
|
||||||
|
*/
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
using bool3_t = std::array<bool, 3>;
|
||||||
|
|
||||||
|
inline bool operator==(const bool3_t& arr, bool value)
|
||||||
|
{
|
||||||
|
return arr[0] == value && arr[1] == value && arr[2] == value;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DrawTriangleParam
|
||||||
|
{
|
||||||
|
AntiAliasingTech aaTech;
|
||||||
|
bool ccw;
|
||||||
|
fVector2 verts[3];
|
||||||
|
float32_t bbox_min_x;
|
||||||
|
float32_t bbox_max_x;
|
||||||
|
float32_t bbox_min_y;
|
||||||
|
float32_t bbox_max_y;
|
||||||
|
bool3_t tlBorder;
|
||||||
|
float32_t area;
|
||||||
|
iFloat3 edgesDX, edgesDY;
|
||||||
|
|
||||||
|
iFloat3 halfEdge;
|
||||||
|
iFloat3 quaterEdge;
|
||||||
|
iFloat3 oneEighthEdge;
|
||||||
|
|
||||||
|
Rasterizer::DebugParam debugParam;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { MIN_TILE_WIDTH_IN_PIXELS = 64 };
|
||||||
|
|
||||||
|
void _fillPixel(const DrawTriangleParam& param, int32_t xLB, int32_t yLB, uint32_t mask, Rasterizer::DrawTriangleCallback callback)
|
||||||
|
{
|
||||||
|
fVector2 pixel(xLB + 0.5f, yLB + 0.5f);
|
||||||
|
const fVector2 v0(param.verts[0]), v1(param.verts[1]), v2(param.verts[2]);
|
||||||
|
|
||||||
|
float32_t w0 = (v2 - v1).crossProduct(pixel - v2);
|
||||||
|
float32_t w1 = (v0 - v2).crossProduct(pixel - v0);
|
||||||
|
float32_t w2 = (v1 - v0).crossProduct(pixel - v1);
|
||||||
|
|
||||||
|
fVector3 t = fVector3(w0 / param.area, (param.ccw ? w1 : w2) / param.area, (param.ccw ? w2 : w1) / param.area);
|
||||||
|
|
||||||
|
callback(std::make_pair(xLB, yLB), t, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _fillTile(const DrawTriangleParam& param, int32_t currentTileSize,
|
||||||
|
int32_t xLB, int32_t yLB, Rasterizer::DrawTriangleCallback callback)
|
||||||
|
{
|
||||||
|
for (int32_t yIndex = yLB; yIndex < yLB + currentTileSize; yIndex++)
|
||||||
|
{
|
||||||
|
for (int32_t xIndex = xLB; xIndex < xLB + currentTileSize; xIndex++)
|
||||||
|
{
|
||||||
|
_fillPixel(param, xIndex, yIndex, ~0, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _drawPixel_without_AA(DrawTriangleParam& param,
|
||||||
|
int32_t xLB, int32_t yLB, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||||
|
Rasterizer::DrawTriangleCallback callback)
|
||||||
|
{
|
||||||
|
iFloat3 centerEdges(edgesLB);
|
||||||
|
centerEdges.add(param.halfEdge);
|
||||||
|
|
||||||
|
bool insideTriangle =
|
||||||
|
(centerEdges.x > 0 || (param.tlBorder[0] && centerEdges.x == 0)) &&
|
||||||
|
(centerEdges.y > 0 || (param.tlBorder[1] && centerEdges.y == 0)) &&
|
||||||
|
(centerEdges.z > 0 || (param.tlBorder[2] && centerEdges.z == 0));
|
||||||
|
|
||||||
|
if (insideTriangle)
|
||||||
|
{
|
||||||
|
_fillPixel(param, xLB, yLB, ~0, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _drawPixel_with_MSAA2X2(DrawTriangleParam& param,
|
||||||
|
int32_t x, int32_t y, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||||
|
Rasterizer::DrawTriangleCallback callback)
|
||||||
|
{
|
||||||
|
// 2x2 MSAA;
|
||||||
|
iFloat3 sampleEdgesDX(param.edgesDX);
|
||||||
|
sampleEdgesDX.mul(iFloat::kHalf);
|
||||||
|
|
||||||
|
iFloat3 sampleEdgesDY(param.edgesDY);
|
||||||
|
sampleEdgesDY.mul(iFloat::kHalf);
|
||||||
|
|
||||||
|
iFloat3 firstSampleEdges(edgesLB);
|
||||||
|
firstSampleEdges.add(param.quaterEdge); // 0.25f
|
||||||
|
|
||||||
|
iFloat3 rowEdges(firstSampleEdges);
|
||||||
|
|
||||||
|
uint32_t mask = 0;
|
||||||
|
for (int32_t yIndex = 0; yIndex < 2; yIndex++)
|
||||||
|
{
|
||||||
|
iFloat3 sampleEdges(rowEdges);
|
||||||
|
|
||||||
|
for (int32_t xIndex = 0; xIndex < 2; xIndex++)
|
||||||
|
{
|
||||||
|
bool sampleInsideTriangle =
|
||||||
|
(sampleEdges.x > 0 || (param.tlBorder[0] && sampleEdges.x == 0)) &&
|
||||||
|
(sampleEdges.y > 0 || (param.tlBorder[1] && sampleEdges.y == 0)) &&
|
||||||
|
(sampleEdges.z > 0 || (param.tlBorder[2] && sampleEdges.z == 0));
|
||||||
|
|
||||||
|
if (sampleInsideTriangle)
|
||||||
|
{
|
||||||
|
mask |= (1 << (yIndex * 2 + xIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleEdges.sub(sampleEdgesDY);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowEdges.add(sampleEdgesDX);
|
||||||
|
}
|
||||||
|
|
||||||
|
_fillPixel(param, x, y, mask, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _drawPixel_with_MSAA4X4(DrawTriangleParam& param,
|
||||||
|
int32_t x, int32_t y, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||||
|
Rasterizer::DrawTriangleCallback callback)
|
||||||
|
{
|
||||||
|
// 4x4 MSAA;
|
||||||
|
iFloat3 sampleEdgesDX(param.edgesDX);
|
||||||
|
sampleEdgesDX.mul(iFloat::kQuater);
|
||||||
|
|
||||||
|
iFloat3 sampleEdgesDY(param.edgesDY);
|
||||||
|
sampleEdgesDY.mul(iFloat::kQuater);
|
||||||
|
|
||||||
|
iFloat3 firstSampleEdges(edgesLB);
|
||||||
|
firstSampleEdges.add(param.oneEighthEdge); // 0.125f
|
||||||
|
|
||||||
|
iFloat3 rowEdges(firstSampleEdges);
|
||||||
|
|
||||||
|
uint32_t mask = 0;
|
||||||
|
for (int32_t yIndex = 0; yIndex < 4; yIndex++)
|
||||||
|
{
|
||||||
|
iFloat3 sampleEdges(rowEdges);
|
||||||
|
|
||||||
|
for (int32_t xIndex = 0; xIndex < 4; xIndex++)
|
||||||
|
{
|
||||||
|
bool sampleInsideTriangle =
|
||||||
|
(sampleEdges.x > 0 || (param.tlBorder[0] && sampleEdges.x == 0)) &&
|
||||||
|
(sampleEdges.y > 0 || (param.tlBorder[1] && sampleEdges.y == 0)) &&
|
||||||
|
(sampleEdges.z > 0 || (param.tlBorder[2] && sampleEdges.z == 0));
|
||||||
|
|
||||||
|
if (sampleInsideTriangle)
|
||||||
|
{
|
||||||
|
mask |= (1 << (yIndex * 4 + xIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleEdges.sub(sampleEdgesDY);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowEdges.add(sampleEdgesDX);
|
||||||
|
}
|
||||||
|
|
||||||
|
_fillPixel(param, x, y, mask, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _drawPixel(DrawTriangleParam& param,
|
||||||
|
int32_t xLB, int32_t yLB, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||||
|
Rasterizer::DrawTriangleCallback callback)
|
||||||
|
{
|
||||||
|
switch (param.aaTech)
|
||||||
|
{
|
||||||
|
case AntiAliasingTech::AA_MSAA_4X4:
|
||||||
|
_drawPixel_with_MSAA4X4(param, xLB, yLB, edgesLB, intersectant, callback);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AntiAliasingTech::AA_MSAA_2X2:
|
||||||
|
_drawPixel_with_MSAA2X2(param, xLB, yLB, edgesLB, intersectant, callback);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AntiAliasingTech::AA_None:
|
||||||
|
default:
|
||||||
|
_drawPixel_without_AA(param, xLB, yLB, edgesLB, intersectant, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _drawTriangle_Tile(DrawTriangleParam& param, int32_t currentTileSize,
|
||||||
|
int32_t xLB, int32_t yLB, const iFloat3& edgesLB, const bool3_t& intersectant,
|
||||||
|
Rasterizer::DrawTriangleCallback callback)
|
||||||
|
{
|
||||||
|
if (intersectant==false)
|
||||||
|
{
|
||||||
|
_fillTile(param, currentTileSize, xLB, yLB, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTileSize == 1)
|
||||||
|
{
|
||||||
|
_drawPixel(param, xLB, yLB, edgesLB, intersectant, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t subTileSize = currentTileSize / 4;
|
||||||
|
|
||||||
|
iFloat3 subTileEdgesDX(param.edgesDX);
|
||||||
|
subTileEdgesDX.mul(subTileSize);
|
||||||
|
|
||||||
|
iFloat3 subTileEdgesDY(param.edgesDY);
|
||||||
|
subTileEdgesDY.mul(subTileSize);
|
||||||
|
|
||||||
|
iFloat3 rowRejectEdges(edgesLB);
|
||||||
|
iFloat3 rowAcceptEdges(edgesLB);
|
||||||
|
iFloat3 rowLBEdges(edgesLB);
|
||||||
|
|
||||||
|
for (size_t v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
if (intersectant[v])
|
||||||
|
{
|
||||||
|
if (subTileEdgesDX[v] > 0) rowRejectEdges[v] += subTileEdgesDX[v];
|
||||||
|
else if (subTileEdgesDX[v] < 0) rowAcceptEdges[v] += subTileEdgesDX[v];
|
||||||
|
|
||||||
|
if (subTileEdgesDY[v] > 0) rowAcceptEdges[v] -= subTileEdgesDY[v];
|
||||||
|
else if (subTileEdgesDY[v] < 0) rowRejectEdges[v] -= subTileEdgesDY[v];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t yPos = yLB;
|
||||||
|
for (int32_t yIndex = 0; yIndex < 4; yIndex++)
|
||||||
|
{
|
||||||
|
if (yPos > param.bbox_max_y)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yPos + subTileSize >= param.bbox_min_y)
|
||||||
|
{
|
||||||
|
iFloat3 subTileLBEdges(rowLBEdges);
|
||||||
|
iFloat3 subTileRjectEdges(rowRejectEdges);
|
||||||
|
iFloat3 subTileAcceptEdges(rowAcceptEdges);
|
||||||
|
|
||||||
|
int32_t xPos = xLB;
|
||||||
|
for (int32_t xIndex = 0; xIndex < 4; xIndex++)
|
||||||
|
{
|
||||||
|
if (xPos > param.bbox_max_x)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xPos + subTileSize >= param.bbox_min_x)
|
||||||
|
{
|
||||||
|
bool rejected =
|
||||||
|
(intersectant[0] && (subTileRjectEdges[0] < 0 || (!param.tlBorder[0] && subTileRjectEdges[0] == 0))) ||
|
||||||
|
(intersectant[1] && (subTileRjectEdges[1] < 0 || (!param.tlBorder[1] && subTileRjectEdges[1] == 0))) ||
|
||||||
|
(intersectant[2] && (subTileRjectEdges[2] < 0 || (!param.tlBorder[2] && subTileRjectEdges[2] == 0)));
|
||||||
|
|
||||||
|
if (!rejected)
|
||||||
|
{
|
||||||
|
bool3_t newIntersectant = intersectant;
|
||||||
|
for (size_t v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
if (intersectant[v])
|
||||||
|
{
|
||||||
|
if (subTileAcceptEdges[v] > 0 || (subTileAcceptEdges[v] == 0 && param.tlBorder[v]))
|
||||||
|
{
|
||||||
|
newIntersectant[v] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_drawTriangle_Tile(param, subTileSize, xPos, yPos, subTileLBEdges, newIntersectant, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xPos += subTileSize;
|
||||||
|
subTileLBEdges.sub(subTileEdgesDY);
|
||||||
|
|
||||||
|
for (size_t v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
if (intersectant[v])
|
||||||
|
{
|
||||||
|
subTileRjectEdges[v] -= subTileEdgesDY[v];
|
||||||
|
subTileAcceptEdges[v] -= subTileEdgesDY[v];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yPos += subTileSize;
|
||||||
|
rowLBEdges.add(subTileEdgesDX);
|
||||||
|
for (size_t v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
if (intersectant[v])
|
||||||
|
{
|
||||||
|
rowRejectEdges[v] += subTileEdgesDX[v];
|
||||||
|
rowAcceptEdges[v] += subTileEdgesDX[v];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rasterizer::drawTriangleLarrabee(AntiAliasingTech aaTech, int32_t canvasWidth, int32_t canvasHeight,
|
||||||
|
const fVector2& v0, const fVector2& v1, const fVector2& v2,
|
||||||
|
DrawTriangleCallback callback, bool ccw, const DebugParam* debugParam)
|
||||||
|
{
|
||||||
|
assert(canvasWidth >= MIN_TILE_WIDTH_IN_PIXELS && canvasHeight >= MIN_TILE_WIDTH_IN_PIXELS);
|
||||||
|
assert(canvasWidth% MIN_TILE_WIDTH_IN_PIXELS == 0 && canvasHeight% MIN_TILE_WIDTH_IN_PIXELS == 0);
|
||||||
|
|
||||||
|
if (canvasWidth < MIN_TILE_WIDTH_IN_PIXELS || canvasHeight < MIN_TILE_WIDTH_IN_PIXELS)
|
||||||
|
{
|
||||||
|
return; //canvas too small
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canvasWidth % MIN_TILE_WIDTH_IN_PIXELS != 0 && canvasHeight % MIN_TILE_WIDTH_IN_PIXELS != 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//The minimum size of the tile is 64 pixels,
|
||||||
|
int32_t tileSize = MIN_TILE_WIDTH_IN_PIXELS;
|
||||||
|
while(canvasWidth >= tileSize && canvasHeight >= tileSize &&
|
||||||
|
canvasWidth% tileSize ==0 && canvasHeight% tileSize ==0)
|
||||||
|
{
|
||||||
|
tileSize *= 4;
|
||||||
|
}
|
||||||
|
tileSize /= 4;
|
||||||
|
|
||||||
|
DrawTriangleParam param;
|
||||||
|
param.aaTech = aaTech;
|
||||||
|
int32_t widthInTiles = canvasWidth / tileSize;
|
||||||
|
|
||||||
|
//Whether the three input vertices are in the agreed clockwise order or not,
|
||||||
|
// it indicates that the triangle is invisible
|
||||||
|
bool isCCW = (v1 - v0).crossProduct(v2 - v1)>0;
|
||||||
|
if (isCCW != ccw) return;
|
||||||
|
|
||||||
|
//By default, the order is counterclockwise. So if the input data is clockwise, a reversal is needed.
|
||||||
|
// Swap v1 and v2, and then reverse it back when the final callback is made
|
||||||
|
param.ccw = ccw;
|
||||||
|
param.verts[0] = v0;
|
||||||
|
param.verts[1] = ccw ? v1 : v2;
|
||||||
|
param.verts[2] = ccw ? v2 : v1;
|
||||||
|
param.area = (param.verts[1] - param.verts[0]).crossProduct(param.verts[2] - param.verts[1]);
|
||||||
|
|
||||||
|
//get window coordinates bounding box
|
||||||
|
param.bbox_min_x = MathUtil::min3(v0.x, v1.x, v2.x);
|
||||||
|
param.bbox_max_x = MathUtil::max3(v0.x, v1.x, v2.x);
|
||||||
|
param.bbox_min_y = MathUtil::min3(v0.y, v1.y, v2.y);
|
||||||
|
param.bbox_max_y = MathUtil::max3(v0.y, v1.y, v2.y);
|
||||||
|
|
||||||
|
//canvas size
|
||||||
|
iFloat iCanvasWidth(canvasWidth);
|
||||||
|
iFloat iCanvasHeight(canvasHeight);
|
||||||
|
|
||||||
|
// clip triangles that are fully outside the scissor rect (scissor rect = whole window)
|
||||||
|
if (param.bbox_max_x < 0 || param.bbox_max_y < 0 || param.bbox_min_x >= canvasWidth || param.bbox_min_y >= canvasHeight)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (param.bbox_min_x < 0) param.bbox_min_x = 0;
|
||||||
|
if (param.bbox_min_y < 0) param.bbox_min_y = 0;
|
||||||
|
if (param.bbox_max_x > canvasWidth - 1.f) param.bbox_max_x = canvasWidth - 1.f;
|
||||||
|
if (param.bbox_max_y > canvasHeight - 1.f) param.bbox_max_y = canvasHeight - 1.f;
|
||||||
|
|
||||||
|
// tile range
|
||||||
|
int32_t first_tile_x = (int32_t)(param.bbox_min_x / tileSize);
|
||||||
|
int32_t first_tile_y = (int32_t)(param.bbox_min_y / tileSize);
|
||||||
|
int32_t last_tile_x = (int32_t)(param.bbox_max_x / tileSize);
|
||||||
|
int32_t last_tile_y = (int32_t)(param.bbox_max_y / tileSize);
|
||||||
|
|
||||||
|
//The first tile is the tile at the lower left corner within the bounding box range covered by the triangle
|
||||||
|
iFloat firstTileX = iFloat(first_tile_x * tileSize);
|
||||||
|
iFloat firstTileY = iFloat(first_tile_y * tileSize);
|
||||||
|
|
||||||
|
iFloat3 edgesFirstLB; //The edge value at the lower left corner of the first tile
|
||||||
|
iFloat3 tileEdgesDX, tileEdgesDY;
|
||||||
|
iFloat3 edgesReject, edgesAccept;
|
||||||
|
|
||||||
|
iFloat2 vertices[3];
|
||||||
|
for (size_t i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
vertices[i] = iFloat2(param.verts[i].x, param.verts[i].y);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
size_t v_end = (v + 1) % 3;
|
||||||
|
param.edgesDX[v] = vertices[v_end].x - vertices[v].x;
|
||||||
|
param.edgesDY[v] = vertices[v_end].y - vertices[v].y;
|
||||||
|
|
||||||
|
param.halfEdge[v] = (param.edgesDX[v]- param.edgesDY[v]) * iFloat::kHalf;
|
||||||
|
param.quaterEdge[v] = (param.edgesDX[v] - param.edgesDY[v]) * iFloat::kQuater;
|
||||||
|
param.oneEighthEdge[v] = (param.edgesDX[v] - param.edgesDY[v]) * iFloat::kOneEighth;
|
||||||
|
|
||||||
|
tileEdgesDX[v] = param.edgesDX[v] * tileSize;
|
||||||
|
tileEdgesDY[v] = param.edgesDY[v] * tileSize;
|
||||||
|
|
||||||
|
//(V0,V1) X (V0, P) = (x1-x0)(py-y0)-(y1-y0)(px-x0)
|
||||||
|
edgesFirstLB[v] = param.edgesDX[v] * (firstTileY - vertices[v].y)
|
||||||
|
- param.edgesDY[v] * (firstTileX - vertices[v].x);
|
||||||
|
|
||||||
|
// Top-left rule:
|
||||||
|
// shift top-left edges ever so slightly outward to make the top-left edges be
|
||||||
|
// the tie-breakers when rasterizing adjacent triangles
|
||||||
|
if ((vertices[v_end].y == vertices[v].y && vertices[v_end].x < vertices[v].x) ||
|
||||||
|
vertices[v_end].y < vertices[v].y)
|
||||||
|
{
|
||||||
|
param.tlBorder[v] = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
param.tlBorder[v] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edgesReject[v] = edgesAccept[v] = edgesFirstLB[v];
|
||||||
|
|
||||||
|
if (tileEdgesDX[v] > 0) edgesReject[v] += tileEdgesDX[v];
|
||||||
|
else if (tileEdgesDX[v] < 0) edgesAccept[v] += tileEdgesDX[v];
|
||||||
|
|
||||||
|
if (tileEdgesDY[v] > 0) edgesAccept[v] -= tileEdgesDY[v];
|
||||||
|
else if (tileEdgesDY[v] < 0) edgesReject[v] -= tileEdgesDY[v];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debugParam != nullptr)
|
||||||
|
{
|
||||||
|
param.debugParam.debug = debugParam->debug;
|
||||||
|
param.debugParam.szOutputFileName = debugParam->szOutputFileName;
|
||||||
|
param.debugParam.x = debugParam->x;
|
||||||
|
param.debugParam.y = debugParam->y;
|
||||||
|
|
||||||
|
if (param.debugParam.debug) {
|
||||||
|
param.debugParam.fpOutput = fopen(debugParam->szOutputFileName, "w");
|
||||||
|
|
||||||
|
fprintf(param.debugParam.fpOutput, "===== Triangle ====\n");
|
||||||
|
for (int32_t i = 0; i < 3; i++) {
|
||||||
|
fprintf(param.debugParam.fpOutput, "v%d=(%f,%f)[%lld,%lld]\n", i,
|
||||||
|
param.verts[i].x, param.verts[i].y, vertices[i].x.s3132, vertices[i].y.s3132);
|
||||||
|
}
|
||||||
|
fprintf(param.debugParam.fpOutput, "===== TileRange ====\n");
|
||||||
|
fprintf(param.debugParam.fpOutput,
|
||||||
|
"tile_x={%d, %d}\ntile_y={%d, %d}\n",
|
||||||
|
first_tile_x, last_tile_x, first_tile_y, last_tile_y);
|
||||||
|
fprintf(param.debugParam.fpOutput,
|
||||||
|
"FirstTile=(%f,%f)[%lld,%lld]\n", firstTileX.to_float(), firstTileY.to_float(),
|
||||||
|
firstTileX.s3132, firstTileY.s3132
|
||||||
|
);
|
||||||
|
|
||||||
|
fprintf(param.debugParam.fpOutput, "===== Edge ====\n");
|
||||||
|
for (int32_t i = 0; i < 3; i++) {
|
||||||
|
fprintf(param.debugParam.fpOutput, "DX%d=(%f)[%lld]\tDY%d=(%f)[%lld]\n",
|
||||||
|
i,
|
||||||
|
param.edgesDX[i].to_float(), param.edgesDX[i].s3132,
|
||||||
|
i,
|
||||||
|
param.edgesDY[i].to_float(), param.edgesDY[i].s3132);
|
||||||
|
}
|
||||||
|
fprintf(param.debugParam.fpOutput, "\n");
|
||||||
|
for (int32_t i = 0; i < 3; i++) {
|
||||||
|
fprintf(param.debugParam.fpOutput, "Edge%d=(%lld)*(y-%lld)-(%lld)*(x-%lld)\n\t=(%f)*(y-%f)-(%f)*(x-%f)\n", i,
|
||||||
|
param.edgesDX[i].s3132, vertices[i].y.s3132, param.edgesDY[i].s3132, vertices[i].x.s3132,
|
||||||
|
param.edgesDX[i].to_float(), vertices[i].y.to_float(), param.edgesDY[i].to_float(), vertices[i].x.to_float()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fprintf(param.debugParam.fpOutput, "EdgeFirstLB=(%f,%f,%f)[%lld,%lld,%lld]\n",
|
||||||
|
edgesFirstLB.x.to_float(), edgesFirstLB.y.to_float(), edgesFirstLB.z.to_float(),
|
||||||
|
edgesFirstLB.x.s3132, edgesFirstLB.y.s3132, edgesFirstLB.z.s3132
|
||||||
|
);
|
||||||
|
for (int32_t i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
fprintf(param.debugParam.fpOutput, "EdgeLB.%d=%lld*(%lld-%lld)-%lld*(%lld-%lld)\n", i,
|
||||||
|
param.edgesDX[i].s3132, firstTileY.s3132, vertices[i].y.s3132,
|
||||||
|
param.edgesDY[i].s3132, firstTileX.s3132, vertices[i].x.s3132
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(param.debugParam.fpOutput, "TopLeft=%s,%s,%s\n",
|
||||||
|
param.tlBorder[0] ? "true" : "false", param.tlBorder[1] ? "true" : "false", param.tlBorder[2] ? "true" : "false"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iFloat3 rowEdges(edgesFirstLB);
|
||||||
|
int32_t yLB = first_tile_y * tileSize;
|
||||||
|
|
||||||
|
for (int32_t tile_y = first_tile_y; tile_y <= last_tile_y; tile_y++)
|
||||||
|
{
|
||||||
|
iFloat3 edgesTileLB(rowEdges);
|
||||||
|
iFloat3 tileEdgesReject(edgesReject);
|
||||||
|
iFloat3 tileEdgesAccept(edgesAccept);
|
||||||
|
|
||||||
|
int32_t xLB = first_tile_x * tileSize;
|
||||||
|
|
||||||
|
for (int32_t tile_x = first_tile_x; tile_x <= last_tile_x; tile_x++)
|
||||||
|
{
|
||||||
|
//If the tile is excluded by any edge,
|
||||||
|
// it indicates that the tile is completely outside the triangle and does not require rendering
|
||||||
|
bool rejected =
|
||||||
|
((tileEdgesReject[0] < 0 || (!param.tlBorder[0] && tileEdgesReject[0] == 0))) ||
|
||||||
|
((tileEdgesReject[1] < 0 || (!param.tlBorder[1] && tileEdgesReject[1] == 0))) ||
|
||||||
|
((tileEdgesReject[2] < 0 || (!param.tlBorder[2] && tileEdgesReject[2] == 0)));
|
||||||
|
|
||||||
|
if (!rejected)
|
||||||
|
{
|
||||||
|
//draw tile
|
||||||
|
bool3_t intersectant;
|
||||||
|
for (size_t v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
//whether the accepting vertex of this tile is on the "outside" of the three edges,
|
||||||
|
// that is, it may intersect or be completely outside
|
||||||
|
intersectant[v] = (tileEdgesAccept[v] < 0 || (tileEdgesAccept[v] == 0 && !param.tlBorder[v]));
|
||||||
|
}
|
||||||
|
|
||||||
|
_drawTriangle_Tile(param, tileSize, xLB, yLB, edgesTileLB, intersectant, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//x setp
|
||||||
|
edgesTileLB.sub(tileEdgesDY);
|
||||||
|
tileEdgesReject.sub(tileEdgesDY);
|
||||||
|
tileEdgesAccept.sub(tileEdgesDY);
|
||||||
|
xLB += tileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//y step
|
||||||
|
rowEdges.add(tileEdgesDX);
|
||||||
|
edgesReject.add(tileEdgesDX);
|
||||||
|
edgesAccept.add(tileEdgesDX);
|
||||||
|
yLB += tileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debugParam != nullptr && debugParam->debug)
|
||||||
|
{
|
||||||
|
fclose(param.debugParam.fpOutput);
|
||||||
|
param.debugParam.fpOutput = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
void Rasterizer::drawTriangleBoundingBox(int32_t canvasWidth, int32_t canvasHeight,
|
||||||
|
const fVector2& _v0, const fVector2& _v1, const fVector2& _v2,
|
||||||
|
DrawTriangleCallback callback, bool ccw)
|
||||||
|
{
|
||||||
|
//Whether the three input vertices are in the agreed clockwise order or not,
|
||||||
|
// it indicates that the triangle is invisible
|
||||||
|
bool isCCW = (_v1 - _v0).crossProduct(_v2 - _v1) > 0;
|
||||||
|
if (isCCW != ccw) return;
|
||||||
|
|
||||||
|
fVector2 v[3];
|
||||||
|
v[0] = _v0;
|
||||||
|
v[1] = ccw ? _v1 : _v2;
|
||||||
|
v[2] = ccw ? _v2 : _v1;
|
||||||
|
|
||||||
|
float32_t xmin = MathUtil::min3(v[0].x, v[1].x, v[2].x);
|
||||||
|
float32_t ymin = MathUtil::min3(v[0].y, v[1].y, v[2].y);
|
||||||
|
float32_t xmax = MathUtil::max3(v[0].x, v[1].x, v[2].x);
|
||||||
|
float32_t ymax = MathUtil::max3(v[0].y, v[1].y, v[2].y);
|
||||||
|
|
||||||
|
int32_t x0 = MathUtil::max2(0, (int32_t)std::floor(xmin));
|
||||||
|
int32_t x1 = MathUtil::min2(canvasWidth - 1, (int32_t)std::floor(xmax));
|
||||||
|
int32_t y0 = MathUtil::max2(0, (int32_t)std::floor(ymin));
|
||||||
|
int32_t y1 = MathUtil::min2(canvasHeight - 1, (int32_t)std::floor(ymax));
|
||||||
|
|
||||||
|
float32_t area = (v[1] - v[0]).crossProduct(v[2] - v[1]);
|
||||||
|
|
||||||
|
//edge function
|
||||||
|
// e(x,y)=(x1-x0)(y-y0)-(y1-y0))(x-x0)=ax+by+c
|
||||||
|
// a=y0-y1, b=x1-x0, c=(y1-y0)x0-(x1-x0)y0
|
||||||
|
|
||||||
|
iFloat edge_a[3], edge_b[3], edge_c[3];
|
||||||
|
bool edge_tl[3]; //is top-left edge?
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 3; i++) {
|
||||||
|
int32_t next = (i + 1) % 3;
|
||||||
|
iFloat2 v0 = iFloat2(v[i].x, v[i].y);
|
||||||
|
iFloat2 v1 = iFloat2(v[next].x, v[next].y);
|
||||||
|
|
||||||
|
edge_a[i] = v0.y - v1.y;
|
||||||
|
edge_b[i] = v1.x - v0.x;
|
||||||
|
edge_c[i] = (v1.y - v0.y) * v0.x - (v1.x - v0.x) * v0.y;
|
||||||
|
edge_tl[i] = (edge_a[i] != 0) ? (edge_a[i] > 0) : (edge_b[i] < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t y = y0; y <= y1; y++) {
|
||||||
|
for (int32_t x = x0; x <= x1; x++) {
|
||||||
|
|
||||||
|
iFloat2 iPixel(iFloat(x) + iFloat::kHalf, iFloat(y) + iFloat::kHalf);
|
||||||
|
|
||||||
|
bool outsideTriangle = false;
|
||||||
|
for (int32_t i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
iFloat edge = edge_a[i] * iPixel.x + edge_b[i] * iPixel.y + edge_c[i];
|
||||||
|
bool insideEdge = edge.s3132 > 0 || (edge.s3132 == 0 && edge_tl[i]);
|
||||||
|
|
||||||
|
if (!insideEdge) {
|
||||||
|
outsideTriangle = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (outsideTriangle) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fVector2 pixel(x + 0.5f, y + 0.5f);
|
||||||
|
float32_t w0 = (v[2] - v[1]).crossProduct(pixel - v[2]);
|
||||||
|
float32_t w1 = (v[0] - v[2]).crossProduct(pixel - v[0]);
|
||||||
|
float32_t w2 = (v[1] - v[0]).crossProduct(pixel - v[1]);
|
||||||
|
|
||||||
|
fVector3 t = fVector3(w0 / area, (ccw ? w1 : w2) / area, (ccw ? w2 : w1) / area);
|
||||||
|
|
||||||
|
callback(std::make_pair(x, y), t, ~0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -51,7 +51,7 @@ void CameraComponent::setCameraDefine(const CameraComponent::CameraDefine& camer
|
|||||||
m_viewProjMatrix = matProj * matView;
|
m_viewProjMatrix = matProj * matView;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraComponent::render(const fMatrix4& transParent, RenderQueue& queue) const
|
void CameraComponent::buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe) const
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ SceneComponent::~SceneComponent()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneComponent::render(const fMatrix4& transParent, RenderQueue& queue) const
|
void SceneComponent::buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe) const
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ void LightComponent::setLightDefine(const LightDefine& lightDefine)
|
|||||||
m_define = lightDefine;
|
m_define = lightDefine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightComponent::render(const fMatrix4& transParent, RenderQueue& queue) const
|
void LightComponent::buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe) const
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "scene/component/dvc_mesh_component.h"
|
#include "scene/component/dvc_mesh_component.h"
|
||||||
#include "asset/dvc_mesh.h"
|
#include "asset/dvc_mesh.h"
|
||||||
#include "pipe/dvc_renderable_entity.h"
|
#include "pipe/dvc_renderable_entity.h"
|
||||||
#include "pipe/dvc_render_queue.h"
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@@ -27,9 +27,9 @@ void MeshComponent::setMesh(MeshConstPtr mesh)
|
|||||||
m_mesh = mesh;
|
m_mesh = mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshComponent::render(const fMatrix4& transParent, RenderQueue& queue) const
|
void MeshComponent::buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe) const
|
||||||
{
|
{
|
||||||
SceneComponent::render(transParent, queue);
|
SceneComponent::buildRenderableQueue(transParent, pipe);
|
||||||
|
|
||||||
int32_t primitiveCounts = m_mesh->getPrimitiveCounts();
|
int32_t primitiveCounts = m_mesh->getPrimitiveCounts();
|
||||||
for (int32_t i = 0; i < primitiveCounts; i++)
|
for (int32_t i = 0; i < primitiveCounts; i++)
|
||||||
@@ -37,7 +37,7 @@ void MeshComponent::render(const fMatrix4& transParent, RenderQueue& queue) cons
|
|||||||
Mesh::PrimitiveConstPtr primitivePtr = m_mesh->getPrimitive(i);
|
Mesh::PrimitiveConstPtr primitivePtr = m_mesh->getPrimitive(i);
|
||||||
|
|
||||||
RenderablePtr renderable = std::make_shared<RenderableEntity>(primitivePtr, transParent);
|
RenderablePtr renderable = std::make_shared<RenderableEntity>(primitivePtr, transParent);
|
||||||
queue.pushRenderable(renderable);
|
pipe.pushRenderable(renderable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
#include "scene/dvc_scene.h"
|
#include "scene/dvc_scene.h"
|
||||||
#include "scene/dvc_scene_node.h"
|
#include "scene/dvc_scene_node.h"
|
||||||
#include "device/dvc_buffer.h"
|
|
||||||
#include "device/dvc_buffer_view.h"
|
|
||||||
#include "device/dvc_buffer_accessor.h"
|
|
||||||
#include "scene/component/dvc_camera_component.h"
|
#include "scene/component/dvc_camera_component.h"
|
||||||
|
|
||||||
DV_CORE_BEGIN_NAMESPACE
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
@@ -33,79 +30,6 @@ void Scene::clear(void)
|
|||||||
m_rootSceneNode->clear();
|
m_rootSceneNode->clear();
|
||||||
}
|
}
|
||||||
m_rootSceneNode = nullptr;
|
m_rootSceneNode = nullptr;
|
||||||
|
|
||||||
//clear assets
|
|
||||||
m_meshArray.clear();
|
|
||||||
|
|
||||||
//clear device resources
|
|
||||||
m_bufferAccessorArray.clear();
|
|
||||||
m_bufferViewArray.clear();
|
|
||||||
m_deviceBufferArray.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceBufferPtr Scene::newDeviceBuffer()
|
|
||||||
{
|
|
||||||
DeviceBufferPtr deviceBuffer = std::make_shared<DeviceBuffer>();
|
|
||||||
m_deviceBufferArray.push_back(deviceBuffer);
|
|
||||||
return deviceBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceBufferConstPtr Scene::getDeviceBuffer(int32_t index) const
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= m_deviceBufferArray.size())
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return m_deviceBufferArray[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceBufferViewPtr Scene::newDeviceBufferView(DeviceBufferConstPtr buffer, size_t offset, size_t length, size_t stride)
|
|
||||||
{
|
|
||||||
DeviceBufferViewPtr deviceBufferView = std::make_shared<DeviceBufferView>(buffer, offset, length, stride);
|
|
||||||
m_bufferViewArray.push_back(deviceBufferView);
|
|
||||||
return deviceBufferView;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceBufferViewPtr Scene::getDeviceBufferView(int32_t index) const
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= m_bufferViewArray.size())
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return m_bufferViewArray[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceBufferAccessorPtr Scene::newDeviceBufferAccessor(DeviceBufferViewConstPtr bufferView, size_t offset,
|
|
||||||
size_t count, ComponentType componentType, DataType dataType)
|
|
||||||
{
|
|
||||||
DeviceBufferAccessorPtr deviceBufferAccessor = std::make_shared<DeviceBufferAccessor>(
|
|
||||||
bufferView, offset, count, componentType, dataType);
|
|
||||||
m_bufferAccessorArray.push_back(deviceBufferAccessor);
|
|
||||||
return deviceBufferAccessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceBufferAccessorPtr Scene::getDeviceBufferAccessor(int32_t index) const
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= m_bufferAccessorArray.size())
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return m_bufferAccessorArray[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t Scene::pushNewMeshAsset(MeshPtr mesh)
|
|
||||||
{
|
|
||||||
m_meshArray.push_back(mesh);
|
|
||||||
return (int32_t)(m_meshArray.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
MeshConstPtr Scene::getMesh(int32_t index) const
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= m_meshArray.size())
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return m_meshArray[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneNodePtr Scene::newSceneNode(const std::string& name)
|
SceneNodePtr Scene::newSceneNode(const std::string& name)
|
||||||
@@ -120,4 +44,9 @@ SceneNodePtr Scene::getRootSceneNode(void) const
|
|||||||
return m_rootSceneNode;
|
return m_rootSceneNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::buildRenderableQueue(RenderPipe& pipe) const
|
||||||
|
{
|
||||||
|
getRootSceneNode()->buildRenderableQueue(fMatrix4::IDENTITY, pipe);
|
||||||
|
}
|
||||||
|
|
||||||
DV_CORE_END_NAMESPACE
|
DV_CORE_END_NAMESPACE
|
||||||
|
|||||||
@@ -89,18 +89,18 @@ SceneComponentConstPtr SceneNode::getComponent(size_t index) const
|
|||||||
return m_componentArray[index];
|
return m_componentArray[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneNode::buildRenderQueue(const fMatrix4& transParent, RenderQueue& queue)
|
void SceneNode::buildRenderableQueue(const fMatrix4& transParent, RenderPipe& pipe)
|
||||||
{
|
{
|
||||||
fMatrix4 transform = m_transform * transParent;
|
fMatrix4 transform = m_transform * transParent;
|
||||||
|
|
||||||
for (auto component : m_componentArray)
|
for (auto component : m_componentArray)
|
||||||
{
|
{
|
||||||
component->render(transform, queue);
|
component->buildRenderableQueue(transform, pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto child : m_childen)
|
for (auto child : m_childen)
|
||||||
{
|
{
|
||||||
child->buildRenderQueue(transform, queue);
|
child->buildRenderableQueue(transform, pipe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include "shader/dvc_shader_functions.h"
|
||||||
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
#include "asset/dvc_texture.h"
|
||||||
|
|
||||||
|
DV_CORE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
fVector4 shader::texture2D(const RenderPipe& pipe, const TextureInfo& textureInfo, const fVector2& uv, const fVector4& defaultValue)
|
||||||
|
{
|
||||||
|
if (!(textureInfo.texture)) return defaultValue;
|
||||||
|
fVector3 uvTransform = textureInfo.uvTransform * fVector3(uv, 1);
|
||||||
|
return textureInfo.texture->sample(uvTransform.xy());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DV_CORE_END_NAMESPACE
|
||||||
@@ -30,12 +30,14 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
#ifdef DV_SYS_WINDOWS
|
#ifdef DV_SYS_WINDOWS
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#################
|
||||||
|
# sub dictionary
|
||||||
|
#################
|
||||||
|
add_subdirectory(standard)
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
add_library(dv_standard_shaders SHARED
|
||||||
|
dll_main.cpp
|
||||||
|
vs_standard.h
|
||||||
|
vs_standard.cpp
|
||||||
|
fs_debug_solid_color.h
|
||||||
|
fs_debug_solid_color.cpp
|
||||||
|
fs_debug_show_texture.h
|
||||||
|
fs_debug_show_texture.cpp
|
||||||
|
fs_debug_texture_coordinates.h
|
||||||
|
fs_debug_texture_coordinates.cpp
|
||||||
|
fs_debug_geometry_normal.h
|
||||||
|
fs_debug_geometry_normal.cpp
|
||||||
|
fs_classic_phong.h
|
||||||
|
fs_classic_phong.cpp
|
||||||
|
fs_pbr_gltf.h
|
||||||
|
fs_pbr_gltf.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_definitions(-DDV_SHADER_EXPORTS)
|
||||||
|
|
||||||
|
target_include_directories(dv_standard_shaders
|
||||||
|
PRIVATE
|
||||||
|
${DV_AUTO_INCLUDE_PATH}
|
||||||
|
${DV_CORE_INCLUDE_PATH}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(dv_standard_shaders
|
||||||
|
dv_core
|
||||||
|
)
|
||||||
|
|
||||||
|
#################
|
||||||
|
# copy runtime dll(for debug)
|
||||||
|
#################
|
||||||
|
add_custom_command(
|
||||||
|
TARGET dv_standard_shaders POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_standard_shaders> ${CMAKE_BINARY_DIR}/source/console/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>/)
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
#include "dv_config.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
|
||||||
|
#include "vs_standard.h"
|
||||||
|
#include "fs_debug_solid_color.h"
|
||||||
|
#include "fs_debug_show_texture.h"
|
||||||
|
#include "fs_debug_texture_coordinates.h"
|
||||||
|
#include "fs_debug_geometry_normal.h"
|
||||||
|
#include "fs_classic_phong.h"
|
||||||
|
#include "fs_pbr_gltf.h"
|
||||||
|
|
||||||
|
class StandardShaderInterface : public davinci::ShaderFileInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual davinci::VertexShaderInterface* getVertexShader(const char* szName) override
|
||||||
|
{
|
||||||
|
auto it = m_vertexShaderMap.find(szName);
|
||||||
|
if (it != m_vertexShaderMap.end()) return it->second;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual davinci::FragementShaderInterface* getFragementShader(const char* szName) override
|
||||||
|
{
|
||||||
|
auto it = m_fragementShaderMap.find(szName);
|
||||||
|
if (it != m_fragementShaderMap.end()) return it->second;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
StandardShaderInterface()
|
||||||
|
{
|
||||||
|
registerVertexShader(new StandardVertexShader(false , false , false));
|
||||||
|
registerVertexShader(new StandardVertexShader(false , false , true));
|
||||||
|
registerVertexShader(new StandardVertexShader(false , true , false));
|
||||||
|
registerVertexShader(new StandardVertexShader(false , true , true));
|
||||||
|
registerVertexShader(new StandardVertexShader(true , false , false));
|
||||||
|
registerVertexShader(new StandardVertexShader(true , false , true));
|
||||||
|
registerVertexShader(new StandardVertexShader(true , true , false));
|
||||||
|
registerVertexShader(new StandardVertexShader(true , true , true));
|
||||||
|
|
||||||
|
registerFragementShader(new DebugFragementShader_SolidColor());
|
||||||
|
registerFragementShader(new DebugFragementShader_ShowTexture());
|
||||||
|
registerFragementShader(new DebugFragementShader_TextureCoordinates());
|
||||||
|
registerFragementShader(new DebugFragementShader_GeometryNormal());
|
||||||
|
registerFragementShader(new ClassicFragementShader_Phong());
|
||||||
|
registerFragementShader(new PbrFragementShader_GLTF());
|
||||||
|
}
|
||||||
|
|
||||||
|
~StandardShaderInterface()
|
||||||
|
{
|
||||||
|
for (auto it = m_vertexShaderMap.begin(); it != m_vertexShaderMap.end(); ++it)
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
m_vertexShaderMap.clear();
|
||||||
|
|
||||||
|
for (auto it = m_fragementShaderMap.begin(); it != m_fragementShaderMap.end(); ++it)
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
m_fragementShaderMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void registerVertexShader(davinci::VertexShaderInterface* vertexShader)
|
||||||
|
{
|
||||||
|
m_vertexShaderMap.insert(std::make_pair(vertexShader->getName(), vertexShader));
|
||||||
|
}
|
||||||
|
void registerFragementShader(davinci::FragementShaderInterface* fragementShader)
|
||||||
|
{
|
||||||
|
m_fragementShaderMap.insert(std::make_pair(fragementShader->getName(), fragementShader));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, davinci::VertexShaderInterface*> m_vertexShaderMap;
|
||||||
|
std::map<std::string, davinci::FragementShaderInterface*> m_fragementShaderMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
__declspec(dllexport) davinci::ShaderFileInterface* ShaderFileInterface()
|
||||||
|
{
|
||||||
|
static StandardShaderInterface theInterface;
|
||||||
|
return &theInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
#include "fs_classic_phong.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
#include "shader/dvc_shader_functions.h"
|
||||||
|
|
||||||
|
using namespace davinci;
|
||||||
|
|
||||||
|
const char* ClassicFragementShader_Phong::getName(void) const
|
||||||
|
{
|
||||||
|
return "classic:phong";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClassicFragementShader_Phong::begin(const davinci::RenderPipe* pipe, davinci::MaterialConstPtr material, const davinci::VertexDesc& veretexDesc)
|
||||||
|
{
|
||||||
|
m_pipe = pipe;
|
||||||
|
const davinci::UniformBuffer& uniformBuffer = m_pipe->getUniformBuffer();
|
||||||
|
|
||||||
|
if(!(material->getParam("u_materialColor", m_materialColor)))
|
||||||
|
{
|
||||||
|
m_materialColor = davinci::fVector4::WHITE;
|
||||||
|
}
|
||||||
|
if(!(material->getParam("u_specularShininess", m_specularShininess)))
|
||||||
|
{
|
||||||
|
m_specularShininess = 64.0f;
|
||||||
|
}
|
||||||
|
if (!(material->getParam("u_specularStrength", m_specularStrength)))
|
||||||
|
{
|
||||||
|
m_specularStrength = 5.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const davinci::fVector3* attribute = (davinci::fVector3*)(uniformBuffer.getAttribute("ambient_light:color")))
|
||||||
|
{
|
||||||
|
m_ambientLightColor = *attribute;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ambientLightColor = davinci::fVector3(0.2f, 0.2f, 0.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const davinci::fVector3* attribute = (davinci::fVector3*)(uniformBuffer.getAttribute("light0:position")))
|
||||||
|
{
|
||||||
|
m_light0Position = *attribute;
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
if (const davinci::fVector3* attribute = (davinci::fVector3*)(uniformBuffer.getAttribute("light0:color")))
|
||||||
|
{
|
||||||
|
m_light0Color = *attribute;
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
if (const davinci::fVector3* attribute = (davinci::fVector3*)(uniformBuffer.getAttribute("camera:eye_pos")))
|
||||||
|
{
|
||||||
|
m_cameraPosition = *attribute;
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
if (const VertexDesc::Element* element = veretexDesc.getElementByType(davinci::VET_POSITION_WORLD))
|
||||||
|
{
|
||||||
|
m_vWorldPosOffset = element->offset / sizeof(float32_t);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
if (const VertexDesc::Element* element = veretexDesc.getElementByType(davinci::VET_NORMAL))
|
||||||
|
{
|
||||||
|
m_vNormalOffset = element->offset / sizeof(float32_t);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicFragementShader_Phong::process(const float32_t* pixelData, davinci::fVector4& color)
|
||||||
|
{
|
||||||
|
fVector3 v_worldpos = *((const fVector3*)(pixelData + m_vWorldPosOffset));
|
||||||
|
fVector3 v_normal = *((const fVector3*)(pixelData + m_vNormalOffset));
|
||||||
|
|
||||||
|
fVector3 toLight = m_light0Position - v_worldpos;
|
||||||
|
toLight.normalise();
|
||||||
|
|
||||||
|
fVector3 toCamera = m_cameraPosition - v_worldpos;
|
||||||
|
toCamera.normalise();
|
||||||
|
|
||||||
|
float32_t ndotl = toLight.dotProduct(v_normal);
|
||||||
|
fVector3 vR = 2 * ndotl*v_normal - toLight;
|
||||||
|
float32_t rdotv = vR.dotProduct(toCamera);
|
||||||
|
|
||||||
|
fVector3 colAmbient = m_ambientLightColor * m_materialColor.xyz();
|
||||||
|
|
||||||
|
fVector3 colDiffuse = shader::max(0.0f, ndotl) * m_light0Color * m_materialColor.xyz();
|
||||||
|
|
||||||
|
float32_t specular = shader::step(0.f, ndotl) * m_specularStrength * shader::pow(shader::max(0.0f, rdotv), m_specularShininess);
|
||||||
|
fVector3 colSpecular = specular * m_light0Color;
|
||||||
|
|
||||||
|
fVector3 final = fVector3::BLACK;
|
||||||
|
final += colAmbient;
|
||||||
|
final += colDiffuse;
|
||||||
|
final += colSpecular;
|
||||||
|
|
||||||
|
color = fVector4(final.saturate(), 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicFragementShader_Phong::end()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
|
||||||
|
class ClassicFragementShader_Phong : public davinci::FragementShaderInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char* getName(void) const;
|
||||||
|
|
||||||
|
virtual bool begin(const davinci::RenderPipe* pipe, davinci::MaterialConstPtr material, const davinci::VertexDesc& veretexDesc) override;
|
||||||
|
virtual void process(const float32_t* pixelData, davinci::fVector4& color) override;
|
||||||
|
virtual void end() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const davinci::RenderPipe* m_pipe = nullptr;
|
||||||
|
davinci::fVector4 m_materialColor = davinci::fVector4::WHITE;
|
||||||
|
float32_t m_specularShininess = 64.0f;
|
||||||
|
float32_t m_specularStrength = 5.0f;
|
||||||
|
|
||||||
|
davinci::fVector3 m_ambientLightColor = davinci::fVector3(0.2f, 0.2f, 0.2f);
|
||||||
|
davinci::fVector3 m_light0Position;
|
||||||
|
davinci::fVector3 m_light0Color;
|
||||||
|
davinci::fVector3 m_cameraPosition;
|
||||||
|
|
||||||
|
size_t m_vWorldPosOffset;
|
||||||
|
size_t m_vNormalOffset;
|
||||||
|
};
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#include "fs_debug_geometry_normal.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "device/dvc_uniform_buffer.h"
|
||||||
|
#include "asset/dvc_texture.h"
|
||||||
|
#include "shader/dvc_shader_functions.h"
|
||||||
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
|
||||||
|
using namespace davinci;
|
||||||
|
|
||||||
|
const char* DebugFragementShader_GeometryNormal::getName(void) const
|
||||||
|
{
|
||||||
|
return "debug:geometry_normal";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DebugFragementShader_GeometryNormal::begin(const RenderPipe* pipe, MaterialConstPtr material, const VertexDesc& veretexDesc)
|
||||||
|
{
|
||||||
|
m_pipe = pipe;
|
||||||
|
|
||||||
|
if (const VertexDesc::Element* element = veretexDesc.getElementByType(VET_NORMAL))
|
||||||
|
{
|
||||||
|
m_vNormalOffset = element->offset / sizeof(float32_t);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugFragementShader_GeometryNormal::process(const float32_t* pixelData, fVector4& color)
|
||||||
|
{
|
||||||
|
const UniformBuffer& uniformBuffer = m_pipe->getUniformBuffer();
|
||||||
|
|
||||||
|
fVector3 v_normal = *((const fVector3*)(pixelData + m_vNormalOffset));
|
||||||
|
|
||||||
|
fVector3 normalColor = v_normal;
|
||||||
|
normalColor.normalise();
|
||||||
|
|
||||||
|
normalColor = normalColor * 0.5f + 0.5f;
|
||||||
|
color = fVector4(normalColor, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugFragementShader_GeometryNormal::end()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
|
||||||
|
class DebugFragementShader_GeometryNormal : public davinci::FragementShaderInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char* getName(void) const;
|
||||||
|
|
||||||
|
virtual bool begin(const davinci::RenderPipe* pipe, davinci::MaterialConstPtr material, const davinci::VertexDesc& veretexDesc) override;
|
||||||
|
virtual void process(const float32_t* pixelData, davinci::fVector4& color) override;
|
||||||
|
virtual void end() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const davinci::RenderPipe* m_pipe = nullptr;
|
||||||
|
size_t m_vNormalOffset;
|
||||||
|
};
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#include "fs_debug_show_texture.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "device/dvc_uniform_buffer.h"
|
||||||
|
#include "asset/dvc_texture.h"
|
||||||
|
#include "shader/dvc_shader_functions.h"
|
||||||
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
|
||||||
|
using namespace davinci;
|
||||||
|
|
||||||
|
const char* DebugFragementShader_ShowTexture::getName(void) const
|
||||||
|
{
|
||||||
|
return "debug:show_texture";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DebugFragementShader_ShowTexture::begin(const RenderPipe* pipe, MaterialConstPtr material, const VertexDesc& veretexDesc)
|
||||||
|
{
|
||||||
|
m_pipe = pipe;
|
||||||
|
|
||||||
|
if (!(material->getParam("u_textureInfo", m_textureInfo)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const VertexDesc::Element* element = veretexDesc.getElementByType(static_cast<VertexElementType>(VET_TEXCOORD_0+m_textureInfo.texCoord)))
|
||||||
|
{
|
||||||
|
m_vTextureCoordinateOffset = element->offset / sizeof(float32_t);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugFragementShader_ShowTexture::process(const float32_t* pixelData, fVector4& color)
|
||||||
|
{
|
||||||
|
const fVector2* v_TextureCoordinate = (const fVector2*)(pixelData + m_vTextureCoordinateOffset);
|
||||||
|
|
||||||
|
fVector4 textureColor = shader::texture2D(*m_pipe, m_textureInfo, (*v_TextureCoordinate), fVector4::WHITE);
|
||||||
|
|
||||||
|
color = textureColor;
|
||||||
|
}
|
||||||
|
void DebugFragementShader_ShowTexture::end()
|
||||||
|
{
|
||||||
|
m_textureInfo.texture.reset();
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
|
||||||
|
class DebugFragementShader_ShowTexture : public davinci::FragementShaderInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char* getName(void) const;
|
||||||
|
|
||||||
|
virtual bool begin(const davinci::RenderPipe* pipe, davinci::MaterialConstPtr material, const davinci::VertexDesc& veretexDesc) override;
|
||||||
|
virtual void process(const float32_t* pixelData, davinci::fVector4& color) override;
|
||||||
|
virtual void end() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const davinci::RenderPipe* m_pipe = nullptr;
|
||||||
|
|
||||||
|
davinci::TextureInfo m_textureInfo;
|
||||||
|
size_t m_vTextureCoordinateOffset;
|
||||||
|
};
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#include "fs_debug_solid_color.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
|
||||||
|
using namespace davinci;
|
||||||
|
|
||||||
|
const char* DebugFragementShader_SolidColor::getName(void) const
|
||||||
|
{
|
||||||
|
return "debug:solid_color";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DebugFragementShader_SolidColor::begin(const RenderPipe* pipe, MaterialConstPtr material, const VertexDesc& veretexDesc)
|
||||||
|
{
|
||||||
|
if (!(material->getParam("u_solidColor", m_solidColor)))
|
||||||
|
{
|
||||||
|
m_solidColor = davinci::fVector4::WHITE;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugFragementShader_SolidColor::process(const float32_t* pixelData, fVector4& color)
|
||||||
|
{
|
||||||
|
color = m_solidColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugFragementShader_SolidColor::end()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
|
||||||
|
class DebugFragementShader_SolidColor : public davinci::FragementShaderInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char* getName(void) const;
|
||||||
|
|
||||||
|
virtual bool begin(const davinci::RenderPipe* pipe, davinci::MaterialConstPtr material, const davinci::VertexDesc& veretexDesc) override;
|
||||||
|
virtual void process(const float32_t* pixelData, davinci::fVector4& color) override;
|
||||||
|
virtual void end() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
davinci::fVector4 m_solidColor = davinci::fVector4::WHITE;
|
||||||
|
};
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#include "fs_debug_texture_coordinates.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "device/dvc_uniform_buffer.h"
|
||||||
|
#include "asset/dvc_texture.h"
|
||||||
|
#include "shader/dvc_shader_functions.h"
|
||||||
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
|
||||||
|
using namespace davinci;
|
||||||
|
|
||||||
|
const char* DebugFragementShader_TextureCoordinates::getName(void) const
|
||||||
|
{
|
||||||
|
return "debug:texture_coordinates";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DebugFragementShader_TextureCoordinates::begin(const RenderPipe* pipe, MaterialConstPtr material, const VertexDesc& veretexDesc)
|
||||||
|
{
|
||||||
|
m_pipe = pipe;
|
||||||
|
|
||||||
|
if (!(material->getParam("u_texCoord", m_texCoord)))
|
||||||
|
{
|
||||||
|
m_texCoord = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const VertexDesc::Element* element = veretexDesc.getElementByType(static_cast<VertexElementType>(VET_TEXCOORD_0+m_texCoord)))
|
||||||
|
{
|
||||||
|
m_vTextureCoordinateOffset = element->offset / sizeof(float32_t);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugFragementShader_TextureCoordinates::process(const float32_t* pixelData, fVector4& color)
|
||||||
|
{
|
||||||
|
const fVector2* v_uv = (const fVector2*)(pixelData + m_vTextureCoordinateOffset);
|
||||||
|
|
||||||
|
fVector2 uv = *v_uv;
|
||||||
|
float uv_x = uv.x - std::floor(uv.x);
|
||||||
|
float uv_y = uv.y - std::floor(uv.y);
|
||||||
|
|
||||||
|
color = fVector4(uv_x, uv_y, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugFragementShader_TextureCoordinates::end()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
|
||||||
|
class DebugFragementShader_TextureCoordinates : public davinci::FragementShaderInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char* getName(void) const;
|
||||||
|
|
||||||
|
virtual bool begin(const davinci::RenderPipe* pipe, davinci::MaterialConstPtr material, const davinci::VertexDesc& veretexDesc) override;
|
||||||
|
virtual void process(const float32_t* pixelData, davinci::fVector4& color) override;
|
||||||
|
virtual void end() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const davinci::RenderPipe* m_pipe = nullptr;
|
||||||
|
|
||||||
|
int32_t m_texCoord=0;
|
||||||
|
size_t m_vTextureCoordinateOffset;
|
||||||
|
};
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#include "fs_pbr_gltf.h"
|
||||||
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
|
||||||
|
using namespace davinci;
|
||||||
|
|
||||||
|
const char* PbrFragementShader_GLTF::getName(void) const
|
||||||
|
{
|
||||||
|
return "pbr:gltf";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PbrFragementShader_GLTF::begin(const RenderPipe* pipe, MaterialConstPtr material, const VertexDesc& veretexDesc)
|
||||||
|
{
|
||||||
|
m_pipe = pipe;
|
||||||
|
const UniformBuffer& uniformBuffer = m_pipe->getUniformBuffer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PbrFragementShader_GLTF::process(const float32_t* pixelData, fVector4& color)
|
||||||
|
{
|
||||||
|
color = fVector4::BLUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PbrFragementShader_GLTF::end()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
|
||||||
|
class PbrFragementShader_GLTF : public davinci::FragementShaderInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char* getName(void) const;
|
||||||
|
|
||||||
|
virtual bool begin(const davinci::RenderPipe* pipe, davinci::MaterialConstPtr material, const davinci::VertexDesc& veretexDesc) override;
|
||||||
|
virtual void process(const float32_t* pixelData, davinci::fVector4& color) override;
|
||||||
|
virtual void end() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const davinci::RenderPipe* m_pipe = nullptr;
|
||||||
|
davinci::MaterialConstPtr m_material;
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
#include "vs_standard.h"
|
||||||
|
#include "device/dvc_buffer_accessor.h"
|
||||||
|
#include "math/dvc_vector2.h"
|
||||||
|
#include "math/dvc_vector3.h"
|
||||||
|
#include "math/dvc_matrix4.h"
|
||||||
|
#include "pipe/dvc_render_pipe.h"
|
||||||
|
#include "device/dvc_uniform_buffer.h"
|
||||||
|
|
||||||
|
StandardVertexShader::StandardVertexShader(bool withWorldPos, bool withNormal, bool withTexCoord0)
|
||||||
|
: m_withWorldPos(withWorldPos)
|
||||||
|
, m_withNormal(withNormal)
|
||||||
|
, m_withTexCoord0(withTexCoord0)
|
||||||
|
{
|
||||||
|
m_name = "standard";
|
||||||
|
|
||||||
|
m_inputAccessors[davinci::VET_POSITION_MODEL] = nullptr;
|
||||||
|
m_outputVertexDesc.addElement("v_ndc_pos", davinci::VET_POSITION_NDC, davinci::CT_Float32, davinci::DT_Vec3);
|
||||||
|
|
||||||
|
if (withWorldPos)
|
||||||
|
{
|
||||||
|
m_outputVertexDesc.addElement("v_world_pos", davinci::VET_POSITION_WORLD, davinci::CT_Float32, davinci::DT_Vec3);
|
||||||
|
}
|
||||||
|
m_name += withWorldPos ? "+worldpos" : "-worldpos";
|
||||||
|
|
||||||
|
if (withNormal)
|
||||||
|
{
|
||||||
|
m_inputAccessors[davinci::VET_NORMAL] = nullptr;
|
||||||
|
m_outputVertexDesc.addElement("v_normal", davinci::VET_NORMAL, davinci::CT_Float32, davinci::DT_Vec3);
|
||||||
|
}
|
||||||
|
m_name += withNormal ? "+normal" : "-normal";
|
||||||
|
|
||||||
|
if (withTexCoord0)
|
||||||
|
{
|
||||||
|
m_inputAccessors[davinci::VET_TEXCOORD_0] = nullptr;
|
||||||
|
m_outputVertexDesc.addElement("v_uv", davinci::VET_TEXCOORD_0, davinci::CT_Float32, davinci::DT_Vec2);
|
||||||
|
}
|
||||||
|
m_name += withTexCoord0 ? "+uv0" : "-uv0";
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardVertexShader::~StandardVertexShader()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardVertexShader::begin(const davinci::RenderPipe* pipe, SetInputAttributeFunc setInputAttributeFunc)
|
||||||
|
{
|
||||||
|
m_pipe = pipe;
|
||||||
|
|
||||||
|
for (auto& pair : m_inputAccessors)
|
||||||
|
{
|
||||||
|
pair.second = setInputAttributeFunc(pair.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(getInputAccessor(davinci::VET_POSITION_MODEL));
|
||||||
|
assert((!m_withNormal) || getInputAccessor(davinci::VET_NORMAL));
|
||||||
|
assert((!m_withTexCoord0) || getInputAccessor(davinci::VET_TEXCOORD_0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardVertexShader::process(size_t index, float32_t* outputVertex)
|
||||||
|
{
|
||||||
|
static const float DEFAULT_POSITION[] = {0.f, 0.f, 0.f};
|
||||||
|
static const float32_t DEFAULT_NORMAL[] = { 0.f, 0.f, 0.f };
|
||||||
|
static const float32_t DEFAULT_TEXCOORD0[] = { 0.f, 0.f};
|
||||||
|
|
||||||
|
const davinci::UniformBuffer& uniformBuffer = m_pipe->getUniformBuffer();
|
||||||
|
|
||||||
|
davinci::DeviceBufferAccessorConstPtr inputPosition = getInputAccessor(davinci::VET_POSITION_MODEL);
|
||||||
|
davinci::DeviceBufferAccessorConstPtr inputNormal = m_withNormal ? getInputAccessor(davinci::VET_NORMAL) : nullptr;
|
||||||
|
davinci::DeviceBufferAccessorConstPtr inputTexcoord0 = m_withTexCoord0 ? getInputAccessor(davinci::VET_TEXCOORD_0) : nullptr;
|
||||||
|
|
||||||
|
davinci::fVector3 a_position(inputPosition ? (const float32_t*)(inputPosition->getElement(index)) : DEFAULT_POSITION);
|
||||||
|
davinci::fVector3 a_normal(inputNormal ? (const float32_t*)(inputNormal->getElement(index)) : DEFAULT_NORMAL);
|
||||||
|
davinci::fVector2 a_uv(inputTexcoord0 ? (const float32_t*)(inputTexcoord0->getElement(index)) : DEFAULT_TEXCOORD0);
|
||||||
|
|
||||||
|
davinci::fMatrix4 mat_world = davinci::fMatrix4::IDENTITY;
|
||||||
|
if (davinci::fMatrix4* p_mat_world = (davinci::fMatrix4*)(uniformBuffer.getAttribute("self:world_transform")))
|
||||||
|
{
|
||||||
|
mat_world = *p_mat_world;
|
||||||
|
}
|
||||||
|
|
||||||
|
davinci::fMatrix4 mat_camera_view_proj = davinci::fMatrix4::IDENTITY;
|
||||||
|
if (davinci::fMatrix4* p_mat_camera_view_proj = (davinci::fMatrix4*)(uniformBuffer.getAttribute("camera:view_proj_mat")))
|
||||||
|
{
|
||||||
|
mat_camera_view_proj = *p_mat_camera_view_proj;
|
||||||
|
}
|
||||||
|
|
||||||
|
davinci::fVector3 vertexWorldPos = mat_world * a_position;
|
||||||
|
|
||||||
|
//output NDC position
|
||||||
|
{
|
||||||
|
davinci::fVector3 vertexNDCPos = mat_camera_view_proj * vertexWorldPos;
|
||||||
|
memcpy((char*)outputVertex + m_outputVertexDesc.getElementByType(davinci::VET_POSITION_NDC)->offset, &vertexNDCPos, sizeof(davinci::fVector3));
|
||||||
|
}
|
||||||
|
|
||||||
|
//output world position
|
||||||
|
if (m_withWorldPos)
|
||||||
|
{
|
||||||
|
memcpy((char*)outputVertex + m_outputVertexDesc.getElementByType(davinci::VET_POSITION_WORLD)->offset, &vertexWorldPos, sizeof(davinci::fVector3));
|
||||||
|
}
|
||||||
|
|
||||||
|
//output normal
|
||||||
|
if (m_withNormal)
|
||||||
|
{
|
||||||
|
davinci::fMatrix4 matNormal = davinci::fMatrix4::IDENTITY;
|
||||||
|
if (davinci::fMatrix4* p_mat_normal = (davinci::fMatrix4*)(uniformBuffer.getAttribute("self:world_transform_inverse_trans")))
|
||||||
|
{
|
||||||
|
matNormal = *p_mat_normal;
|
||||||
|
}
|
||||||
|
davinci::fVector3 v_normal = (matNormal * davinci::fVector4(a_normal, 0)).xyz().normalise();
|
||||||
|
memcpy((char*)outputVertex + m_outputVertexDesc.getElementByType(davinci::VET_NORMAL)->offset, &v_normal, sizeof(davinci::fVector3));
|
||||||
|
}
|
||||||
|
|
||||||
|
//output uv0
|
||||||
|
if (m_withTexCoord0)
|
||||||
|
{
|
||||||
|
memcpy((char*)outputVertex + m_outputVertexDesc.getElementByType(davinci::VET_TEXCOORD_0)->offset, &a_uv, sizeof(float32_t) * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardVertexShader::end()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "shader/dvc_shader_interface.h"
|
||||||
|
|
||||||
|
|
||||||
|
class StandardVertexShader : public davinci::VertexShaderInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char* getName(void) const {
|
||||||
|
return m_name.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const davinci::VertexDesc& getOutputVertexDesc() const {
|
||||||
|
return m_outputVertexDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t getOutputVertexByteSize(void) const {
|
||||||
|
return m_outputVertexDesc.vertexByteSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void begin(const davinci::RenderPipe* pipe, SetInputAttributeFunc setInputAttributeFunc);
|
||||||
|
virtual void process(size_t index, float32_t* outputVertex);
|
||||||
|
virtual void end();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
davinci::DeviceBufferAccessorConstPtr getInputAccessor(davinci::VertexElementType elementType) const {
|
||||||
|
auto it = m_inputAccessors.find(elementType);
|
||||||
|
if (it != m_inputAccessors.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const davinci::RenderPipe* m_pipe = nullptr;
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
bool m_withWorldPos = false;
|
||||||
|
bool m_withNormal = false;
|
||||||
|
bool m_withTexCoord0 = false;
|
||||||
|
|
||||||
|
typedef std::map<davinci::VertexElementType, davinci::DeviceBufferAccessorConstPtr> InputAccessorMap;
|
||||||
|
InputAccessorMap m_inputAccessors;
|
||||||
|
|
||||||
|
davinci::VertexDesc m_outputVertexDesc;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StandardVertexShader(bool withWorldPos, bool withNormal, bool withTexCoord0);
|
||||||
|
virtual ~StandardVertexShader();
|
||||||
|
};
|
||||||
@@ -30,6 +30,32 @@ set(DV_UTILS_SCENE_SOURCE_FILES
|
|||||||
)
|
)
|
||||||
source_group("source/scene" FILES ${DV_UTILS_SCENE_SOURCE_FILES})
|
source_group("source/scene" FILES ${DV_UTILS_SCENE_SOURCE_FILES})
|
||||||
|
|
||||||
|
#################
|
||||||
|
# camera
|
||||||
|
#################
|
||||||
|
set(DV_UTILS_CAMERA_INCLUDE_FILES
|
||||||
|
include/camera/dvu_default_camera.h
|
||||||
|
)
|
||||||
|
source_group("include/camera" FILES ${DV_UTILS_CAMERA_INCLUDE_FILES})
|
||||||
|
|
||||||
|
set(DV_UTILS_CAMERA_SOURCE_FILES
|
||||||
|
source/camera/dvu_default_camera.cpp
|
||||||
|
)
|
||||||
|
source_group("source/camera" FILES ${DV_UTILS_CAMERA_SOURCE_FILES})
|
||||||
|
|
||||||
|
#################
|
||||||
|
# standard asserts
|
||||||
|
#################
|
||||||
|
set(DV_UTILS_STANDARD_INCLUDE_FILES
|
||||||
|
include/standard/dvu_standard_material.h
|
||||||
|
)
|
||||||
|
source_group("include/standard" FILES ${DV_UTILS_STANDARD_INCLUDE_FILES})
|
||||||
|
|
||||||
|
set(DV_UTILS_STANDARD_SOURCE_FILES
|
||||||
|
source/standard/dvu_standard_material.cpp
|
||||||
|
)
|
||||||
|
source_group("source/standard" FILES ${DV_UTILS_STANDARD_SOURCE_FILES})
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${DV_AUTO_INCLUDE_PATH}
|
${DV_AUTO_INCLUDE_PATH}
|
||||||
${DV_CORE_INCLUDE_PATH}
|
${DV_CORE_INCLUDE_PATH}
|
||||||
@@ -43,6 +69,10 @@ add_library(dv_utils SHARED
|
|||||||
${DV_UTILS_SCENE_SOURCE_FILES}
|
${DV_UTILS_SCENE_SOURCE_FILES}
|
||||||
${DV_UTILS_BUFFER_INCLUDE_FILES}
|
${DV_UTILS_BUFFER_INCLUDE_FILES}
|
||||||
${DV_UTILS_BUFFER_SOURCE_FILES}
|
${DV_UTILS_BUFFER_SOURCE_FILES}
|
||||||
|
${DV_UTILS_CAMERA_INCLUDE_FILES}
|
||||||
|
${DV_UTILS_CAMERA_SOURCE_FILES}
|
||||||
|
${DV_UTILS_STANDARD_INCLUDE_FILES}
|
||||||
|
${DV_UTILS_STANDARD_SOURCE_FILES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(dv_utils
|
target_link_libraries(dv_utils
|
||||||
@@ -60,11 +90,13 @@ target_compile_definitions(dv_utils
|
|||||||
#################
|
#################
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET dv_utils POST_BUILD
|
TARGET dv_utils POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_utils> ${CMAKE_BINARY_DIR}/source/console/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>)
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_utils> ${CMAKE_BINARY_DIR}/source/console/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>/$<TARGET_FILE_NAME:dv_utils>
|
||||||
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET dv_utils POST_BUILD
|
TARGET dv_utils POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_utils> ${CMAKE_BINARY_DIR}/test/unit/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>)
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:dv_utils> ${CMAKE_BINARY_DIR}/test/unit/$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>/$<TARGET_FILE_NAME:dv_utils>
|
||||||
|
)
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# install
|
# install
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvu_config.h"
|
||||||
|
#include "scene/dvc_scene.h"
|
||||||
|
|
||||||
|
DV_UTILS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
bool DV_UTILS_API create_default_camera(davinci::Scene& scene);
|
||||||
|
|
||||||
|
DV_UTILS_END_NAMESPACE
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dvu_config.h"
|
#include "dvu_config.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
#include "scene/dvc_scene.h"
|
#include "scene/dvc_scene.h"
|
||||||
|
|
||||||
DV_UTILS_BEGIN_NAMESPACE
|
DV_UTILS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
bool DV_UTILS_API load_scene_from_gltf(const char* szSceneFiles, davinci::Scene& scene);
|
bool DV_UTILS_API load_scene_from_gltf(const char* szSceneFiles, davinci::Device& device, davinci::Scene& scene);
|
||||||
|
|
||||||
bool DV_UTILS_API export_mesh_to_obj(const davinci::Scene& scene);
|
bool DV_UTILS_API export_mesh_to_obj(const davinci::Device& device, const davinci::Scene& scene);
|
||||||
|
|
||||||
DV_UTILS_END_NAMESPACE
|
DV_UTILS_END_NAMESPACE
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dvu_config.h"
|
||||||
|
#include "dvc_config.h"
|
||||||
|
#include "dvc_pre_declare.h"
|
||||||
|
|
||||||
|
DV_UTILS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
davinci::MaterialPtr DV_UTILS_API create_standard_material(davinci::Device* device, const char* name);
|
||||||
|
|
||||||
|
DV_UTILS_END_NAMESPACE
|
||||||
@@ -17,8 +17,10 @@ bool dump_pixel_buffer(const char* filename, int32_t width, int32_t height,
|
|||||||
case davinci::PF_UINT8_RGBA:
|
case davinci::PF_UINT8_RGBA:
|
||||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA; break;
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA; break;
|
||||||
case davinci::PF_FLOAT32_RGB:
|
case davinci::PF_FLOAT32_RGB:
|
||||||
|
case davinci::PF_UINT8_RGB:
|
||||||
color_type = PNG_COLOR_TYPE_RGB; break;
|
color_type = PNG_COLOR_TYPE_RGB; break;
|
||||||
case davinci::PF_FLOAT32_R:
|
case davinci::PF_FLOAT32_ALPHA:
|
||||||
|
case davinci::PF_UINT8_ALPHA:
|
||||||
color_type = PNG_COLOR_TYPE_GRAY; break;
|
color_type = PNG_COLOR_TYPE_GRAY; break;
|
||||||
default:
|
default:
|
||||||
//not support yet!
|
//not support yet!
|
||||||
@@ -54,9 +56,14 @@ bool dump_pixel_buffer(const char* filename, int32_t width, int32_t height,
|
|||||||
png_write_info(png_ptr, info_ptr);
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
//integer pixelformat
|
//integer pixelformat
|
||||||
if (davinci::PF_UINT8_RGBA == pixelFormat) {
|
if (davinci::PF_UINT8_RGBA == pixelFormat ||
|
||||||
for (int32_t y = 0; y < height; y++) {
|
davinci::PF_UINT8_RGB == pixelFormat ||
|
||||||
const uint32_t* p = (const uint32_t*)pixelData + (height - 1 - y) * width;
|
davinci::PF_UINT8_ALPHA == pixelFormat)
|
||||||
|
{
|
||||||
|
size_t pixelSize = davinci::MathUtil::PixelSize(pixelFormat);
|
||||||
|
for (int32_t y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
const uint8_t* p = (const uint8_t*)pixelData + (height - 1 - y) * width * pixelSize;
|
||||||
png_write_rows(png_ptr, (png_bytepp)&p, 1);
|
png_write_rows(png_ptr, (png_bytepp)&p, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +172,7 @@ bool dump_render_target(const char* baseFilename, const davinci::RenderTarget& r
|
|||||||
_snprintf(szFileName, 256, "%s_depth.png", baseFilename);
|
_snprintf(szFileName, 256, "%s_depth.png", baseFilename);
|
||||||
dump_pixel_buffer(szFileName,
|
dump_pixel_buffer(szFileName,
|
||||||
renderTarget.getWidth(), renderTarget.getHeight(),
|
renderTarget.getWidth(), renderTarget.getHeight(),
|
||||||
&(depth_data[0]), davinci::PF_FLOAT32_R
|
&(depth_data[0]), davinci::PF_FLOAT32_ALPHA
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include "camera/dvu_default_camera.h"
|
||||||
|
#include "scene/dvc_scene_node.h"
|
||||||
|
#include "scene/component/dvc_camera_component.h"
|
||||||
|
|
||||||
|
#include "math/dvc_matrix4.h"
|
||||||
|
#include "math/dvc_vector3.h"
|
||||||
|
#include "math/dvc_vector4.h"
|
||||||
|
|
||||||
|
DV_UTILS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
bool create_default_camera(davinci::Scene& scene)
|
||||||
|
{
|
||||||
|
//------default camera define
|
||||||
|
static const davinci::fVector4 kDefaultCameraRotation(
|
||||||
|
-0.20997299253940582f, 0.3857799470424652f, 0.09062844514846802f, 0.8937962055206299f);
|
||||||
|
static const davinci::fVector3 kDefaultCameraTranslation(
|
||||||
|
7.358891487121582f, 4.958309173583984f, 6.925790786743164f);
|
||||||
|
static const float kDefaultCameraAspectRatio = 1.7777777777777777f;
|
||||||
|
static const float kDefaultCamaraFov = 0.39959652046304894f;
|
||||||
|
static const float kDefaultCameraNearClip = 0.1f;
|
||||||
|
static const float kDefaultCameraFarClip = 100.f;
|
||||||
|
//-----default camera define
|
||||||
|
|
||||||
|
|
||||||
|
//create camera scene node
|
||||||
|
davinci::SceneNodePtr sceneNode = scene.newSceneNode("__DEFAULT_CAMERA__");
|
||||||
|
|
||||||
|
//transform
|
||||||
|
davinci::fMatrix4 transform = davinci::fMatrix4::IDENTITY;
|
||||||
|
|
||||||
|
//rotation
|
||||||
|
transform = davinci::fMatrix4::makeRotate(kDefaultCameraRotation) * transform;
|
||||||
|
|
||||||
|
//translation
|
||||||
|
transform = davinci::fMatrix4::makeTrans(kDefaultCameraTranslation) * transform;
|
||||||
|
sceneNode->setTransform(transform);
|
||||||
|
|
||||||
|
//camera define
|
||||||
|
davinci::CameraComponent::CameraDefine cameraDefine;
|
||||||
|
cameraDefine.aspect = kDefaultCameraAspectRatio;
|
||||||
|
cameraDefine.fov = kDefaultCamaraFov;
|
||||||
|
cameraDefine.nearClip = kDefaultCameraNearClip;
|
||||||
|
cameraDefine.farClip = kDefaultCameraFarClip;
|
||||||
|
|
||||||
|
//camera component
|
||||||
|
davinci::CameraComponentPtr cameraComponent = std::make_shared<davinci::CameraComponent>(sceneNode);
|
||||||
|
cameraComponent->setCameraDefine(cameraDefine);
|
||||||
|
sceneNode->addComponent(std::dynamic_pointer_cast<davinci::SceneComponent>(cameraComponent));
|
||||||
|
|
||||||
|
//add to scene root node
|
||||||
|
scene.getRootSceneNode()->addChild(sceneNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_UTILS_END_NAMESPACE
|
||||||
@@ -1,14 +1,27 @@
|
|||||||
|
//
|
||||||
|
// https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html
|
||||||
|
//
|
||||||
#include "scene/dvu_load_gltf.h"
|
#include "scene/dvu_load_gltf.h"
|
||||||
|
#include "camera/dvu_default_camera.h"
|
||||||
#include "scene/dvc_scene.h"
|
#include "scene/dvc_scene.h"
|
||||||
#include "scene/dvc_scene_node.h"
|
#include "scene/dvc_scene_node.h"
|
||||||
#include "scene/component/dvc_mesh_component.h"
|
#include "scene/component/dvc_mesh_component.h"
|
||||||
#include "scene/component/dvc_camera_component.h"
|
#include "scene/component/dvc_camera_component.h"
|
||||||
#include "scene/component/dvc_light_component.h"
|
#include "scene/component/dvc_light_component.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
#include "device/dvc_buffer_accessor.h"
|
#include "device/dvc_buffer_accessor.h"
|
||||||
#include "asset/dvc_mesh.h"
|
#include "asset/dvc_mesh.h"
|
||||||
|
#include "asset/dvc_image.h"
|
||||||
|
#include "asset/dvc_texture.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
|
||||||
#include "math/dvc_vector3.h"
|
#include "math/dvc_vector3.h"
|
||||||
#include "math/dvc_vector4.h"
|
#include "math/dvc_vector4.h"
|
||||||
|
|
||||||
|
#include "buffer/dvu_dump_buffer.h"
|
||||||
|
|
||||||
|
#include "standard/dvu_standard_material.h"
|
||||||
|
|
||||||
#include <tiny_gltf.h>
|
#include <tiny_gltf.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -90,6 +103,25 @@ davinci::PrimitiveType _getPrimitiveTypeFromGltf(int gltfModelType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
davinci::PixelFormat _getPixelFormatFromGltf(int32_t gltfComponent, int32_t gltfPixelType)
|
||||||
|
{
|
||||||
|
if (gltfPixelType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE)
|
||||||
|
{
|
||||||
|
if (gltfComponent == 1) return davinci::PF_UINT8_ALPHA;
|
||||||
|
else if (gltfComponent == 3) return davinci::PF_UINT8_RGB;
|
||||||
|
else if (gltfComponent == 4) return davinci::PF_UINT8_RGBA;
|
||||||
|
else return davinci::PF_UNKNOWN;
|
||||||
|
}
|
||||||
|
else if (gltfPixelType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
|
||||||
|
{
|
||||||
|
if (gltfComponent == 1) return davinci::PF_UINT16_ALPHA;
|
||||||
|
else if (gltfComponent == 3) return davinci::PF_UINT16_RGB;
|
||||||
|
else if (gltfComponent == 4) return davinci::PF_UINT16_RGBA;
|
||||||
|
else return davinci::PF_UNKNOWN;
|
||||||
|
}
|
||||||
|
else return davinci::PF_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
//from "POSITION/NORMAL/..." to VET_***
|
//from "POSITION/NORMAL/..." to VET_***
|
||||||
davinci::VertexElementType _getElementTypeFromGltf(const std::string& gltfElementType)
|
davinci::VertexElementType _getElementTypeFromGltf(const std::string& gltfElementType)
|
||||||
{
|
{
|
||||||
@@ -106,7 +138,7 @@ davinci::VertexElementType _getElementTypeFromGltf(const std::string& gltfElemen
|
|||||||
|
|
||||||
if (gltfElementType == "POSITION")
|
if (gltfElementType == "POSITION")
|
||||||
{
|
{
|
||||||
return davinci::VET_POSITION;
|
return davinci::VET_POSITION_MODEL;
|
||||||
}
|
}
|
||||||
else if(gltfElementType == "NORMAL")
|
else if(gltfElementType == "NORMAL")
|
||||||
{
|
{
|
||||||
@@ -128,47 +160,301 @@ davinci::VertexElementType _getElementTypeFromGltf(const std::string& gltfElemen
|
|||||||
return davinci::VET_UNKNOWN;
|
return davinci::VET_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _loadDeviceBuffer(const tinygltf::Model& gltfModel, davinci::Scene& scene)
|
davinci::DeviceBufferAccessorPtr _createFloat32BufferAccessorFromNormalizedIntegerType(
|
||||||
|
davinci::Device& device, davinci::Scene& scene,
|
||||||
|
davinci::DeviceBufferAccessorPtr inpuptBufferAccesser)
|
||||||
|
{
|
||||||
|
size_t elementCounts = inpuptBufferAccesser->getCount();
|
||||||
|
davinci::ComponentType inputComponentType = inpuptBufferAccesser->getComponentType();
|
||||||
|
if (inputComponentType != davinci::ComponentType::CT_Uint8 &&
|
||||||
|
inputComponentType != davinci::ComponentType::CT_Uint16 &&
|
||||||
|
inputComponentType != davinci::ComponentType::CT_Uint32)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
davinci::DataType dataType = inpuptBufferAccesser->getDataType();
|
||||||
|
size_t bufferSize = elementCounts * davinci::MathUtil::ComponentSize(davinci::ComponentType::CT_Float32) * davinci::MathUtil::DataTypeSize(dataType);
|
||||||
|
davinci::DeviceBufferPtr newBuffer = device.newDeviceBuffer(bufferSize);
|
||||||
|
|
||||||
|
if (dataType == davinci::DataType::DT_Scalar)
|
||||||
|
{
|
||||||
|
inpuptBufferAccesser->walk([newBuffer, inputComponentType](const uint8_t* ptr, size_t index)
|
||||||
|
{
|
||||||
|
float32_t* target = (float32_t*)(newBuffer->ptr(index * sizeof(float32_t)));
|
||||||
|
if (inputComponentType == davinci::ComponentType::CT_Uint8)
|
||||||
|
{
|
||||||
|
target[0] = ((const uint8_t*)ptr)[0] / (float32_t)0xFF;
|
||||||
|
}
|
||||||
|
else if (inputComponentType == davinci::ComponentType::CT_Uint16)
|
||||||
|
{
|
||||||
|
target[0] = ((const uint16_t*)ptr)[0] / (float32_t)0xFFFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target[0] = ((const uint32_t*)ptr)[0] / (float32_t)0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (dataType == davinci::DataType::DT_Vec2)
|
||||||
|
{
|
||||||
|
inpuptBufferAccesser->walk(
|
||||||
|
[newBuffer, inputComponentType](const uint8_t* ptr, size_t index)
|
||||||
|
{
|
||||||
|
float32_t* target = (float32_t*)(newBuffer->ptr(index * sizeof(float32_t) * 2));
|
||||||
|
if (inputComponentType == davinci::ComponentType::CT_Uint8)
|
||||||
|
{
|
||||||
|
target[0] = ((const uint8_t*)ptr)[0] / (float32_t)0xFF;
|
||||||
|
target[1] = ((const uint8_t*)ptr)[1] / (float32_t)0xFF;
|
||||||
|
}
|
||||||
|
else if (inputComponentType == davinci::ComponentType::CT_Uint16)
|
||||||
|
{
|
||||||
|
target[0] = ((const uint16_t*)ptr)[0] / (float32_t)0xFFFF;
|
||||||
|
target[1] = ((const uint16_t*)ptr)[1] / (float32_t)0xFFFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target[0] = ((const uint32_t*)ptr)[0] / (float32_t)0xFFFFFFFF;
|
||||||
|
target[1] = ((const uint32_t*)ptr)[1] / (float32_t)0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (dataType == davinci::DataType::DT_Vec3)
|
||||||
|
{
|
||||||
|
inpuptBufferAccesser->walk(
|
||||||
|
[newBuffer, inputComponentType](const uint8_t* ptr, size_t index)
|
||||||
|
{
|
||||||
|
float32_t* target = (float32_t*)(newBuffer->ptr(index * sizeof(float32_t) * 3));
|
||||||
|
if (inputComponentType == davinci::ComponentType::CT_Uint8)
|
||||||
|
{
|
||||||
|
target[0] = ((const uint8_t*)ptr)[0] / (float32_t)0xFF;
|
||||||
|
target[1] = ((const uint8_t*)ptr)[1] / (float32_t)0xFF;
|
||||||
|
target[2] = ((const uint8_t*)ptr)[2] / (float32_t)0xFF;
|
||||||
|
}
|
||||||
|
else if (inputComponentType == davinci::ComponentType::CT_Uint16)
|
||||||
|
{
|
||||||
|
target[0] = ((const uint16_t*)ptr)[0] / (float32_t)0xFFFF;
|
||||||
|
target[1] = ((const uint16_t*)ptr)[1] / (float32_t)0xFFFF;
|
||||||
|
target[2] = ((const uint16_t*)ptr)[2] / (float32_t)0xFFFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target[0] = ((const uint32_t*)ptr)[0] / (float32_t)0xFFFFFFFF;
|
||||||
|
target[1] = ((const uint32_t*)ptr)[1] / (float32_t)0xFFFFFFFF;
|
||||||
|
target[2] = ((const uint32_t*)ptr)[2] / (float32_t)0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (dataType == davinci::DataType::DT_Vec4)
|
||||||
|
{
|
||||||
|
inpuptBufferAccesser->walk(
|
||||||
|
[newBuffer, inputComponentType](const uint8_t* ptr, size_t index)
|
||||||
|
{
|
||||||
|
float32_t* target = (float32_t*)(newBuffer->ptr(index * sizeof(float32_t) * 4));
|
||||||
|
if (inputComponentType == davinci::ComponentType::CT_Uint8)
|
||||||
|
{
|
||||||
|
target[0] = ((const uint8_t*)ptr)[0] / (float32_t)0xFF;
|
||||||
|
target[1] = ((const uint8_t*)ptr)[1] / (float32_t)0xFF;
|
||||||
|
target[2] = ((const uint8_t*)ptr)[2] / (float32_t)0xFF;
|
||||||
|
target[3] = ((const uint8_t*)ptr)[3] / (float32_t)0xFF;
|
||||||
|
}
|
||||||
|
else if (inputComponentType == davinci::ComponentType::CT_Uint16)
|
||||||
|
{
|
||||||
|
target[0] = ((const uint16_t*)ptr)[0] / (float32_t)0xFFFF;
|
||||||
|
target[1] = ((const uint16_t*)ptr)[1] / (float32_t)0xFFFF;
|
||||||
|
target[2] = ((const uint16_t*)ptr)[2] / (float32_t)0xFFFF;
|
||||||
|
target[3] = ((const uint16_t*)ptr)[3] / (float32_t)0xFFFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target[0] = ((const uint32_t*)ptr)[0] / (float32_t)0xFFFFFFFF;
|
||||||
|
target[1] = ((const uint32_t*)ptr)[1] / (float32_t)0xFFFFFFFF;
|
||||||
|
target[2] = ((const uint32_t*)ptr)[2] / (float32_t)0xFFFFFFFF;
|
||||||
|
target[3] = ((const uint32_t*)ptr)[3] / (float32_t)0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
davinci::DeviceBufferViewPtr newBufferViewer = device.newDeviceBufferView(newBuffer, 0, bufferSize, 0);
|
||||||
|
return device.newDeviceBufferAccessor(newBufferViewer, 0, elementCounts, davinci::ComponentType::CT_Float32, dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
davinci::DeviceBufferAccessorPtr _createSupportedPrimitiveAttributeBufferAccessor(
|
||||||
|
davinci::Device& device, davinci::Scene& scene,
|
||||||
|
davinci::VertexElementType vetType, davinci::DeviceBufferAccessorPtr inpuptBufferAccesser)
|
||||||
|
{
|
||||||
|
if (!inpuptBufferAccesser) return nullptr;
|
||||||
|
davinci::ComponentType componentType = inpuptBufferAccesser->getComponentType();
|
||||||
|
davinci::DataType dataType = inpuptBufferAccesser->getDataType();
|
||||||
|
|
||||||
|
switch (vetType)
|
||||||
|
{
|
||||||
|
case davinci::VET_POSITION_MODEL:
|
||||||
|
case davinci::VET_NORMAL:
|
||||||
|
case davinci::VET_BINORMAL:
|
||||||
|
if (componentType == davinci::ComponentType::CT_Float32 && dataType == davinci::DataType::DT_Vec3)
|
||||||
|
{
|
||||||
|
return inpuptBufferAccesser;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case davinci::VET_TANGENT:
|
||||||
|
if (componentType == davinci::ComponentType::CT_Float32 && dataType == davinci::DataType::DT_Vec4)
|
||||||
|
{
|
||||||
|
return inpuptBufferAccesser;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case davinci::VET_TEXCOORD_0:
|
||||||
|
case davinci::VET_TEXCOORD_1:
|
||||||
|
case davinci::VET_TEXCOORD_2:
|
||||||
|
case davinci::VET_TEXCOORD_3:
|
||||||
|
case davinci::VET_TEXCOORD_4:
|
||||||
|
case davinci::VET_TEXCOORD_5:
|
||||||
|
case davinci::VET_TEXCOORD_6:
|
||||||
|
case davinci::VET_TEXCOORD_7:
|
||||||
|
if (dataType == davinci::DataType::DT_Vec2)
|
||||||
|
{
|
||||||
|
if (componentType == davinci::ComponentType::CT_Float32)
|
||||||
|
{
|
||||||
|
return inpuptBufferAccesser;
|
||||||
|
}
|
||||||
|
else if (componentType == davinci::ComponentType::CT_Uint8 || componentType == davinci::ComponentType::CT_Uint16)
|
||||||
|
{
|
||||||
|
return _createFloat32BufferAccessorFromNormalizedIntegerType(device, scene, inpuptBufferAccesser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case davinci::VET_COLOR_0:
|
||||||
|
case davinci::VET_COLOR_1:
|
||||||
|
case davinci::VET_COLOR_2:
|
||||||
|
case davinci::VET_COLOR_3:
|
||||||
|
case davinci::VET_COLOR_4:
|
||||||
|
case davinci::VET_COLOR_5:
|
||||||
|
case davinci::VET_COLOR_6:
|
||||||
|
case davinci::VET_COLOR_7:
|
||||||
|
if (dataType == davinci::DataType::DT_Vec3 || dataType == davinci::DataType::DT_Vec4)
|
||||||
|
{
|
||||||
|
if (componentType == davinci::ComponentType::CT_Float32)
|
||||||
|
{
|
||||||
|
return inpuptBufferAccesser;
|
||||||
|
}
|
||||||
|
else if (componentType == davinci::ComponentType::CT_Uint8 || componentType == davinci::ComponentType::CT_Uint16)
|
||||||
|
{
|
||||||
|
return _createFloat32BufferAccessorFromNormalizedIntegerType(device, scene, inpuptBufferAccesser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case davinci::VET_JOINTS_0:
|
||||||
|
case davinci::VET_JOINTS_1:
|
||||||
|
case davinci::VET_JOINTS_2:
|
||||||
|
case davinci::VET_JOINTS_3:
|
||||||
|
case davinci::VET_JOINTS_4:
|
||||||
|
case davinci::VET_JOINTS_5:
|
||||||
|
case davinci::VET_JOINTS_6:
|
||||||
|
case davinci::VET_JOINTS_7:
|
||||||
|
if (dataType == davinci::DataType::DT_Vec4)
|
||||||
|
{
|
||||||
|
if (componentType == davinci::ComponentType::CT_Uint8 || componentType == davinci::ComponentType::CT_Uint16)
|
||||||
|
{
|
||||||
|
return inpuptBufferAccesser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case davinci::VET_WEIGHTS_0:
|
||||||
|
case davinci::VET_WEIGHTS_1:
|
||||||
|
case davinci::VET_WEIGHTS_2:
|
||||||
|
case davinci::VET_WEIGHTS_3:
|
||||||
|
case davinci::VET_WEIGHTS_4:
|
||||||
|
case davinci::VET_WEIGHTS_5:
|
||||||
|
case davinci::VET_WEIGHTS_6:
|
||||||
|
case davinci::VET_WEIGHTS_7:
|
||||||
|
if (dataType == davinci::DataType::DT_Vec4)
|
||||||
|
{
|
||||||
|
if (componentType == davinci::ComponentType::CT_Float32)
|
||||||
|
{
|
||||||
|
return inpuptBufferAccesser;
|
||||||
|
}
|
||||||
|
else if (componentType == davinci::ComponentType::CT_Uint8 || componentType == davinci::ComponentType::CT_Uint16)
|
||||||
|
{
|
||||||
|
return _createFloat32BufferAccessorFromNormalizedIntegerType(device, scene, inpuptBufferAccesser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isSupportedIndicesType(const davinci::DeviceBufferAccessorConstPtr accesserBuffer)
|
||||||
|
{
|
||||||
|
if (!accesserBuffer) return false;
|
||||||
|
davinci::ComponentType componentType = accesserBuffer->getComponentType();
|
||||||
|
davinci::DataType dataType = accesserBuffer->getDataType();
|
||||||
|
|
||||||
|
return componentType == davinci::ComponentType::CT_Uint16 && dataType == davinci::DataType::DT_Scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _loadDeviceBuffer(tinygltf::Model& gltfModel, davinci::Device& device, davinci::Scene& scene)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < gltfModel.buffers.size(); i++)
|
for (size_t i = 0; i < gltfModel.buffers.size(); i++)
|
||||||
{
|
{
|
||||||
const tinygltf::Buffer& gltfBuffer = gltfModel.buffers[i];
|
tinygltf::Buffer& gltfBuffer = gltfModel.buffers[i];
|
||||||
|
|
||||||
davinci::DeviceBufferPtr deviceBufferPtr = scene.newDeviceBuffer();
|
davinci::DeviceBufferPtr deviceBufferPtr = device.newDeviceBuffer(gltfBuffer.data.size());
|
||||||
deviceBufferPtr->init(gltfBuffer.data.size());
|
|
||||||
|
|
||||||
//fill data
|
//fill data
|
||||||
memcpy(deviceBufferPtr->ptr(0), gltfBuffer.data.data(), gltfBuffer.data.size());
|
memcpy(deviceBufferPtr->ptr(0), gltfBuffer.data.data(), gltfBuffer.data.size());
|
||||||
|
|
||||||
|
//set davinci id
|
||||||
|
gltfBuffer.extensions.insert(std::make_pair("DAVINCI_ID", tinygltf::Value((int32_t)deviceBufferPtr->getID())));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _loadBufferView(const tinygltf::Model& gltfModel, davinci::Scene& scene)
|
bool _loadBufferView(tinygltf::Model& gltfModel, davinci::Device& device, davinci::Scene& scene)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < gltfModel.bufferViews.size(); i++)
|
for (size_t i = 0; i < gltfModel.bufferViews.size(); i++)
|
||||||
{
|
{
|
||||||
const tinygltf::BufferView& gltfBufferView = gltfModel.bufferViews[i];
|
tinygltf::BufferView& gltfBufferView = gltfModel.bufferViews[i];
|
||||||
int32_t bufferIndex = gltfBufferView.buffer;
|
tinygltf::Buffer& gltfBuffer = gltfModel.buffers[gltfBufferView.buffer];
|
||||||
davinci::DeviceBufferConstPtr deviceBufferPtr = scene.getDeviceBuffer(bufferIndex);
|
int32_t bufferID = gltfBuffer.extensions["DAVINCI_ID"].GetNumberAsInt();
|
||||||
|
|
||||||
|
davinci::DeviceBufferConstPtr deviceBufferPtr = device.getDeviceBuffer(bufferID);
|
||||||
if (deviceBufferPtr == nullptr)
|
if (deviceBufferPtr == nullptr)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
davinci::DeviceBufferViewPtr bufferViewPtr = scene.newDeviceBufferView(
|
davinci::DeviceBufferViewPtr bufferViewPtr = device.newDeviceBufferView(
|
||||||
deviceBufferPtr, gltfBufferView.byteOffset, gltfBufferView.byteLength, gltfBufferView.byteStride);
|
deviceBufferPtr, gltfBufferView.byteOffset, gltfBufferView.byteLength, gltfBufferView.byteStride);
|
||||||
|
gltfBufferView.extensions.insert(std::make_pair("DAVINCI_ID", tinygltf::Value((int32_t)bufferViewPtr->getID())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _loadBufferAccessor(const tinygltf::Model& gltfModel, davinci::Scene& scene)
|
bool _loadBufferAccessor(tinygltf::Model& gltfModel, davinci::Device& device, davinci::Scene& scene)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < gltfModel.accessors.size(); i++)
|
for (size_t i = 0; i < gltfModel.accessors.size(); i++)
|
||||||
{
|
{
|
||||||
const tinygltf::Accessor& gltfAccessor = gltfModel.accessors[i];
|
tinygltf::Accessor& gltfAccessor = gltfModel.accessors[i];
|
||||||
|
tinygltf::BufferView& gltfBufferView = gltfModel.bufferViews[gltfAccessor.bufferView];
|
||||||
|
int32_t bufferViewID = gltfBufferView.extensions["DAVINCI_ID"].GetNumberAsInt();
|
||||||
|
|
||||||
int32_t bufferViewIndex = gltfAccessor.bufferView;
|
davinci::DeviceBufferViewPtr deviceBufferView = device.getDeviceBufferView(bufferViewID);
|
||||||
davinci::DeviceBufferViewPtr deviceBufferView = scene.getDeviceBufferView(bufferViewIndex);
|
|
||||||
if (deviceBufferView==nullptr)
|
if (deviceBufferView==nullptr)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -186,20 +472,22 @@ bool _loadBufferAccessor(const tinygltf::Model& gltfModel, davinci::Scene& scene
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
davinci::DeviceBufferAccessorPtr bufferAccessor = scene.newDeviceBufferAccessor(
|
davinci::DeviceBufferAccessorPtr bufferAccessor = device.newDeviceBufferAccessor(
|
||||||
deviceBufferView, gltfAccessor.byteOffset, gltfAccessor.count, componentType, dataType);
|
deviceBufferView, gltfAccessor.byteOffset, gltfAccessor.count, componentType, dataType);
|
||||||
|
gltfAccessor.extensions.insert(std::make_pair("DAVINCI_ID", tinygltf::Value((int32_t)bufferAccessor->getID())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _loadMesh(const tinygltf::Model& gltfModel, davinci::Scene& scene)
|
bool _loadMesh(tinygltf::Model& gltfModel, davinci::Device& device, davinci::Scene& scene)
|
||||||
{
|
{
|
||||||
for (size_t i=0; i<gltfModel.meshes.size(); i++)
|
for (size_t i=0; i<gltfModel.meshes.size(); i++)
|
||||||
{
|
{
|
||||||
const tinygltf::Mesh& gltfMesh = gltfModel.meshes[i];
|
tinygltf::Mesh& gltfMesh = gltfModel.meshes[i];
|
||||||
|
|
||||||
davinci::MeshPtr mesh = std::make_shared<davinci::Mesh>(gltfMesh.name);
|
davinci::MeshPtr mesh = device.newMeshAsset(gltfMesh.name);
|
||||||
|
gltfMesh.extensions.insert(std::make_pair("DAVINCI_ID", tinygltf::Value((int32_t)mesh->getID())));
|
||||||
|
|
||||||
for (size_t j=0; j<gltfMesh.primitives.size(); j++)
|
for (size_t j=0; j<gltfMesh.primitives.size(); j++)
|
||||||
{
|
{
|
||||||
@@ -208,31 +496,226 @@ bool _loadMesh(const tinygltf::Model& gltfModel, davinci::Scene& scene)
|
|||||||
davinci::Mesh::PrimitivePtr primitive = mesh->newPrimitive();
|
davinci::Mesh::PrimitivePtr primitive = mesh->newPrimitive();
|
||||||
primitive->type = _getPrimitiveTypeFromGltf(gltfPrimitive.mode);
|
primitive->type = _getPrimitiveTypeFromGltf(gltfPrimitive.mode);
|
||||||
|
|
||||||
|
//apply attributes
|
||||||
std::map<std::string, int>::const_iterator it(gltfPrimitive.attributes.begin());
|
std::map<std::string, int>::const_iterator it(gltfPrimitive.attributes.begin());
|
||||||
std::map<std::string, int>::const_iterator itEnd(gltfPrimitive.attributes.end());
|
std::map<std::string, int>::const_iterator itEnd(gltfPrimitive.attributes.end());
|
||||||
for (; it != itEnd; it++)
|
for (; it != itEnd; it++)
|
||||||
{
|
{
|
||||||
davinci::VertexElementType vetype = _getElementTypeFromGltf(it->first);
|
davinci::VertexElementType vetype = _getElementTypeFromGltf(it->first);
|
||||||
|
int32_t gltfAccessIndex = it->second;
|
||||||
|
if (gltfAccessIndex < 0 || gltfAccessIndex >= gltfModel.accessors.size())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tinygltf::Accessor& gltfAccessor = gltfModel.accessors[gltfAccessIndex];
|
||||||
|
int32_t accessorID = gltfAccessor.extensions["DAVINCI_ID"].GetNumberAsInt();
|
||||||
|
|
||||||
int32_t gltfAccessor = it->second;
|
davinci::DeviceBufferAccessorPtr deviceBufferAccessor = device.getDeviceBufferAccessor(accessorID);
|
||||||
davinci::DeviceBufferAccessorPtr deviceBufferAccessor = scene.getDeviceBufferAccessor(gltfAccessor);
|
|
||||||
if (deviceBufferAccessor ==nullptr)
|
if (deviceBufferAccessor ==nullptr)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//convert to supported primitive buffer(float32)
|
||||||
|
deviceBufferAccessor = _createSupportedPrimitiveAttributeBufferAccessor(device, scene, vetype, deviceBufferAccessor);
|
||||||
|
if (deviceBufferAccessor == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
primitive->attributes.insert(std::make_pair(vetype, deviceBufferAccessor));
|
primitive->attributes.insert(std::make_pair(vetype, deviceBufferAccessor));
|
||||||
}
|
}
|
||||||
|
|
||||||
davinci::DeviceBufferAccessorPtr indicesBufferAccessor = scene.getDeviceBufferAccessor(gltfPrimitive.indices);
|
//apply indices
|
||||||
|
if (gltfPrimitive.indices < 0 || gltfPrimitive.indices >= gltfModel.accessors.size())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tinygltf::Accessor& gltfIndicesAccessor = gltfModel.accessors[gltfPrimitive.indices];
|
||||||
|
int32_t accessorID = gltfIndicesAccessor.extensions["DAVINCI_ID"].GetNumberAsInt();
|
||||||
|
davinci::DeviceBufferAccessorPtr indicesBufferAccessor = device.getDeviceBufferAccessor(accessorID);
|
||||||
if (indicesBufferAccessor == nullptr)
|
if (indicesBufferAccessor == nullptr)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
primitive->indices = indicesBufferAccessor;
|
bool isSupportedType = _isSupportedIndicesType(indicesBufferAccessor);
|
||||||
|
if (!isSupportedType)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.pushNewMeshAsset(mesh);
|
primitive->indices = indicesBufferAccessor;
|
||||||
|
|
||||||
|
//apply material
|
||||||
|
if (gltfPrimitive.material >= 0 && gltfPrimitive.material < gltfModel.materials.size())
|
||||||
|
{
|
||||||
|
tinygltf::Material& gltfMaterial = gltfModel.materials[gltfPrimitive.material];
|
||||||
|
int32_t materialID = gltfMaterial.extensions["DAVINCI_ID"].GetNumberAsInt();
|
||||||
|
davinci::MaterialPtr materialPtr = device.getMaterial(materialID);
|
||||||
|
if (materialPtr == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
primitive->material = materialPtr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr materialPtr = create_standard_material(&device, "classic:phong");
|
||||||
|
materialPtr->setParam("u_materialColor", davinci::fVector4::WHITE);
|
||||||
|
materialPtr->setParam("u_specularShininess", 32.f);
|
||||||
|
materialPtr->setupMaterial();
|
||||||
|
|
||||||
|
primitive->material = materialPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _loadTexture(tinygltf::Model& gltfModel, davinci::Device& device, davinci::Scene& scene)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < gltfModel.images.size(); i++)
|
||||||
|
{
|
||||||
|
tinygltf::Image& gltfImage = gltfModel.images[i];
|
||||||
|
|
||||||
|
davinci::ImagePtr imagePtr = device.newImageAsset();
|
||||||
|
imagePtr->initWithPixelData(device, gltfImage.width, gltfImage.height,
|
||||||
|
_getPixelFormatFromGltf(gltfImage.component, gltfImage.pixel_type), gltfImage.image.data(), gltfImage.image.size());
|
||||||
|
|
||||||
|
gltfImage.extensions.insert(std::make_pair("DAVINCI_ID", tinygltf::Value((int32_t)imagePtr->getID())));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < gltfModel.textures.size(); i++)
|
||||||
|
{
|
||||||
|
tinygltf::Texture& gltfTexture = gltfModel.textures[i];
|
||||||
|
if (gltfTexture.source < 0 || gltfTexture.source >= (int)gltfModel.images.size())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tinygltf::Image& gltfImage = gltfModel.images[gltfTexture.source];
|
||||||
|
if (gltfImage.width <= 0 || gltfImage.height <= 0 || gltfImage.component <= 0 || gltfImage.component > 4)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t imageID = gltfImage.extensions["DAVINCI_ID"].GetNumberAsInt();
|
||||||
|
davinci::ImagePtr imagePtr = device.getImage(imageID);
|
||||||
|
|
||||||
|
davinci::TexturePtr texturePtr = device.newTextureAsset();
|
||||||
|
texturePtr->setImage(imagePtr);
|
||||||
|
|
||||||
|
gltfTexture.extensions.insert(std::make_pair("DAVINCI_ID", tinygltf::Value((int32_t)texturePtr->getID())));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
davinci::TexturePtr _getTexturePtr(tinygltf::Model& gltfModel, davinci::Device& device, int gltfTextureIndex)
|
||||||
|
{
|
||||||
|
if (gltfTextureIndex < 0 || gltfTextureIndex >= gltfModel.textures.size()) return nullptr;
|
||||||
|
tinygltf::Texture& gltfTexture = gltfModel.textures[gltfTextureIndex];
|
||||||
|
|
||||||
|
int32_t textureID = gltfTexture.extensions["DAVINCI_ID"].GetNumberAsInt();
|
||||||
|
return device.getTexture(textureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
davinci::fVector4 _getVector4FromDoubleArray(const std::vector<double>& doubleArray)
|
||||||
|
{
|
||||||
|
if (doubleArray.size() != 4) return davinci::fVector4::ONE;
|
||||||
|
return davinci::fVector4((float32_t)doubleArray[0], (float32_t)doubleArray[1], (float32_t)doubleArray[2], (float32_t)doubleArray[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
davinci::fMatrix3 _getTextureTransform(const tinygltf::ExtensionMap& gltfTextureInfoExternsionMap)
|
||||||
|
{
|
||||||
|
davinci::fMatrix3 textureTransform = davinci::fMatrix3::IDENTITY;
|
||||||
|
|
||||||
|
auto transformExternsions = gltfTextureInfoExternsionMap.find("KHR_texture_transform");
|
||||||
|
if (transformExternsions != gltfTextureInfoExternsionMap.end())
|
||||||
|
{
|
||||||
|
davinci::fVector2 scale = davinci::fVector2::ONE;
|
||||||
|
const tinygltf::Value& scaleArray = transformExternsions->second.Get("scale");
|
||||||
|
if (scaleArray.IsArray() && scaleArray.ArrayLen()>=2 &&
|
||||||
|
scaleArray.Get(0).IsNumber() && scaleArray.Get(1).IsNumber())
|
||||||
|
{
|
||||||
|
scale = davinci::fVector2(
|
||||||
|
(float32_t)(scaleArray.Get(0).GetNumberAsDouble()),
|
||||||
|
(float32_t)(scaleArray.Get(1).GetNumberAsDouble())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
float32_t rotate = 0.f;
|
||||||
|
const tinygltf::Value& rotationValue = transformExternsions->second.Get("rotation");
|
||||||
|
if (rotationValue.IsNumber())
|
||||||
|
{
|
||||||
|
rotate = (float32_t)rotationValue.GetNumberAsDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
davinci::fVector2 offset = davinci::fVector2::ZERO;
|
||||||
|
const tinygltf::Value& offsetArray = transformExternsions->second.Get("offset");
|
||||||
|
if (offsetArray.IsArray() && offsetArray.ArrayLen()>=2 &&
|
||||||
|
offsetArray.Get(0).IsNumber() && offsetArray.Get(1).IsNumber())
|
||||||
|
{
|
||||||
|
offset = davinci::fVector2(
|
||||||
|
(float32_t)(offsetArray.Get(0).GetNumberAsDouble()),
|
||||||
|
(float32_t)(offsetArray.Get(1).GetNumberAsDouble())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
textureTransform = davinci::fMatrix3::makeTrans(offset) *
|
||||||
|
davinci::fMatrix3::makeRotate(rotate) * davinci::fMatrix3::makeScale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return textureTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _loadMaterial(tinygltf::Model& gltfModel, davinci::Device& device, davinci::Scene& scene)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < gltfModel.materials.size(); i++)
|
||||||
|
{
|
||||||
|
tinygltf::Material& gltfMaterial = gltfModel.materials[i];
|
||||||
|
|
||||||
|
//create new material
|
||||||
|
davinci::MaterialPtr materialPtr = create_standard_material(&device, "pbr:gltf");
|
||||||
|
|
||||||
|
//apply matellic roughness info
|
||||||
|
const tinygltf::PbrMetallicRoughness& gltfPBRMetllicRoughness = gltfMaterial.pbrMetallicRoughness;
|
||||||
|
|
||||||
|
//base color texture
|
||||||
|
const tinygltf::TextureInfo& gltfBaseColorTextureInfo = gltfPBRMetllicRoughness.baseColorTexture;
|
||||||
|
davinci::TextureInfo baseColorTextureInfo = davinci::TextureInfo{
|
||||||
|
_getTexturePtr(gltfModel, device, gltfBaseColorTextureInfo.index),
|
||||||
|
gltfBaseColorTextureInfo.texCoord,
|
||||||
|
_getTextureTransform(gltfBaseColorTextureInfo.extensions)
|
||||||
|
};
|
||||||
|
materialPtr->setParam("u_baseColorTextureInfo", baseColorTextureInfo);
|
||||||
|
|
||||||
|
//matallic & roughness texture
|
||||||
|
const tinygltf::TextureInfo& gltfMetalicRoughnessTextureInfo = gltfPBRMetllicRoughness.metallicRoughnessTexture;
|
||||||
|
davinci::TextureInfo metalicRoughnessTextureInfo = davinci::TextureInfo{
|
||||||
|
_getTexturePtr(gltfModel, device, gltfMetalicRoughnessTextureInfo.index),
|
||||||
|
gltfMetalicRoughnessTextureInfo.texCoord,
|
||||||
|
_getTextureTransform(gltfMetalicRoughnessTextureInfo.extensions),
|
||||||
|
};
|
||||||
|
materialPtr->setParam("u_metalicRoughnessTextureInfo", baseColorTextureInfo);
|
||||||
|
materialPtr->setParam("u_metalicFactor", static_cast<float32_t>(gltfPBRMetllicRoughness.metallicFactor));
|
||||||
|
materialPtr->setParam("u_roughnessFactor", static_cast<float32_t>(gltfPBRMetllicRoughness.roughnessFactor));
|
||||||
|
|
||||||
|
//normal texture
|
||||||
|
const tinygltf::NormalTextureInfo& gltfNormalTextureInfo = gltfMaterial.normalTexture;
|
||||||
|
davinci::TextureInfo normalTextureInfo = davinci::TextureInfo{
|
||||||
|
_getTexturePtr(gltfModel, device, gltfNormalTextureInfo.index),
|
||||||
|
gltfNormalTextureInfo.texCoord,
|
||||||
|
_getTextureTransform(gltfNormalTextureInfo.extensions),
|
||||||
|
};
|
||||||
|
materialPtr->setParam("u_normalTextureInfo", normalTextureInfo);
|
||||||
|
materialPtr->setParam("u_normalTextureScale", static_cast<float32_t>(gltfMaterial.normalTexture.scale));
|
||||||
|
|
||||||
|
//load shader
|
||||||
|
if (!(materialPtr->setupMaterial()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gltfMaterial.extensions.insert(std::make_pair("DAVINCI_ID", tinygltf::Value((int32_t)materialPtr->getID())));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -294,8 +777,7 @@ bool _loadLightExternsion(const tinygltf::Model& gltfModel, std::vector<davinci:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _loadSceneNodes(tinygltf::Model& gltfModel, davinci::Device& device, davinci::Scene& scene, const std::vector<davinci::LightComponent::LightDefine>& lightsArray)
|
||||||
bool _loadSceneNodes(const tinygltf::Model& gltfModel, davinci::Scene& scene, const std::vector<davinci::LightComponent::LightDefine>& lightsArray)
|
|
||||||
{
|
{
|
||||||
std::vector<std::pair<bool, davinci::SceneNodePtr>> sceneNodeArray;
|
std::vector<std::pair<bool, davinci::SceneNodePtr>> sceneNodeArray;
|
||||||
|
|
||||||
@@ -321,12 +803,24 @@ bool _loadSceneNodes(const tinygltf::Model& gltfModel, davinci::Scene& scene, co
|
|||||||
{
|
{
|
||||||
transform = davinci::fMatrix4::makeTrans(gltfNode.translation[0], gltfNode.translation[1], gltfNode.translation[2]) * transform;
|
transform = davinci::fMatrix4::makeTrans(gltfNode.translation[0], gltfNode.translation[1], gltfNode.translation[2]) * transform;
|
||||||
}
|
}
|
||||||
|
if(!gltfNode.matrix.empty())
|
||||||
|
{
|
||||||
|
davinci::fMatrix4 matrix(
|
||||||
|
gltfNode.matrix[0], gltfNode.matrix[1], gltfNode.matrix[2], gltfNode.matrix[3],
|
||||||
|
gltfNode.matrix[4], gltfNode.matrix[5], gltfNode.matrix[6], gltfNode.matrix[7],
|
||||||
|
gltfNode.matrix[8], gltfNode.matrix[9], gltfNode.matrix[10], gltfNode.matrix[11],
|
||||||
|
gltfNode.matrix[12], gltfNode.matrix[13], gltfNode.matrix[14], gltfNode.matrix[15]);
|
||||||
|
transform = matrix.transpose() * transform;
|
||||||
|
}
|
||||||
sceneNode->setTransform(transform);
|
sceneNode->setTransform(transform);
|
||||||
|
|
||||||
//add mesh component
|
//add mesh component
|
||||||
if (gltfNode.mesh != -1)
|
if (gltfNode.mesh != -1)
|
||||||
{
|
{
|
||||||
davinci::MeshConstPtr meshPtr = scene.getMesh(gltfNode.mesh);
|
tinygltf::Mesh& gltfMesh = gltfModel.meshes[gltfNode.mesh];
|
||||||
|
int32_t meshID = gltfMesh.extensions["DAVINCI_ID"].GetNumberAsInt();
|
||||||
|
|
||||||
|
davinci::MeshConstPtr meshPtr = device.getMesh(meshID);
|
||||||
if (meshPtr)
|
if (meshPtr)
|
||||||
{
|
{
|
||||||
davinci::MeshComponentPtr meshComponet = std::make_shared<davinci::MeshComponent>(sceneNode);
|
davinci::MeshComponentPtr meshComponet = std::make_shared<davinci::MeshComponent>(sceneNode);
|
||||||
@@ -434,7 +928,7 @@ bool _loadSceneNodes(const tinygltf::Model& gltfModel, davinci::Scene& scene, co
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_scene_from_gltf(const char* szSceneFiles, davinci::Scene& scene)
|
bool load_scene_from_gltf(const char* szSceneFiles, davinci::Device& device, davinci::Scene& scene)
|
||||||
{
|
{
|
||||||
std::filesystem::path sceneFilePath = std::filesystem::path(szSceneFiles);
|
std::filesystem::path sceneFilePath = std::filesystem::path(szSceneFiles);
|
||||||
|
|
||||||
@@ -445,7 +939,10 @@ bool load_scene_from_gltf(const char* szSceneFiles, davinci::Scene& scene)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tinygltf::Model gltfModel;
|
tinygltf::Model gltfModel;
|
||||||
|
|
||||||
tinygltf::TinyGLTF gltf_ctx;
|
tinygltf::TinyGLTF gltf_ctx;
|
||||||
|
gltf_ctx.SetPreserveImageChannels(true);
|
||||||
|
|
||||||
std::string err;
|
std::string err;
|
||||||
std::string warn;
|
std::string warn;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@@ -479,25 +976,37 @@ bool load_scene_from_gltf(const char* szSceneFiles, davinci::Scene& scene)
|
|||||||
//dump to davinci scene
|
//dump to davinci scene
|
||||||
|
|
||||||
//load device buffer
|
//load device buffer
|
||||||
if (!_loadDeviceBuffer(gltfModel, scene))
|
if (!_loadDeviceBuffer(gltfModel, device, scene))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//load buffer view
|
//load buffer view
|
||||||
if (!_loadBufferView(gltfModel, scene))
|
if (!_loadBufferView(gltfModel, device, scene))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//load buffer accessor
|
//load buffer accessor
|
||||||
if (!_loadBufferAccessor(gltfModel, scene))
|
if (!_loadBufferAccessor(gltfModel, device, scene))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//load texture
|
||||||
|
if (!_loadTexture(gltfModel, device, scene))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//load material
|
||||||
|
if (!_loadMaterial(gltfModel, device, scene))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//load mesh
|
//load mesh
|
||||||
if (!_loadMesh(gltfModel, scene))
|
if (!_loadMesh(gltfModel, device, scene))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -510,22 +1019,29 @@ bool load_scene_from_gltf(const char* szSceneFiles, davinci::Scene& scene)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//load scene nodes
|
//load scene nodes
|
||||||
if (!_loadSceneNodes(gltfModel, scene, lightDefine))
|
if (!_loadSceneNodes(gltfModel, device, scene, lightDefine))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//create default camera
|
||||||
|
davinci::SceneNodeConstPtr cameraNode = scene.getNodeWithComponent<davinci::CameraComponent>();
|
||||||
|
if (cameraNode.get()==nullptr)
|
||||||
|
{
|
||||||
|
create_default_camera(scene);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool export_mesh_to_obj(const davinci::Scene& scene)
|
bool export_mesh_to_obj(const davinci::Device& device, const davinci::Scene& scene)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
int32_t meshCounts = scene.getMeshCounts();
|
int32_t meshCounts = device.getMeshCounts();
|
||||||
for (int32_t meshIndex = 0; meshIndex < meshCounts; meshIndex++)
|
for (int32_t meshIndex = 0; meshIndex < meshCounts; meshIndex++)
|
||||||
{
|
{
|
||||||
davinci::MeshConstPtr mesh = scene.getMesh(meshIndex);
|
davinci::MeshConstPtr mesh = device.getMesh(meshIndex);
|
||||||
|
|
||||||
const std::string& meshName = mesh->getName();
|
const std::string& meshName = mesh->getName();
|
||||||
if (meshName.empty()) {
|
if (meshName.empty()) {
|
||||||
@@ -589,30 +1105,9 @@ bool export_mesh_to_obj(const davinci::Scene& scene)
|
|||||||
davinci::DeviceBufferAccessorConstPtr indexBufferAccessor = primitive->indices;
|
davinci::DeviceBufferAccessorConstPtr indexBufferAccessor = primitive->indices;
|
||||||
indexBufferAccessor->walk3([=](const uint8_t* ptr0, const uint8_t* ptr1, const uint8_t* ptr2, size_t index) {
|
indexBufferAccessor->walk3([=](const uint8_t* ptr0, const uint8_t* ptr1, const uint8_t* ptr2, size_t index) {
|
||||||
|
|
||||||
uint32_t indice0, indice1, indice2;
|
uint32_t indice0 = *((uint16_t*)ptr0) + 1;
|
||||||
if (indexBufferAccessor->getComponentType() == davinci::CT_Uint16)
|
uint32_t indice1 = *((uint16_t*)ptr1) + 1;
|
||||||
{
|
uint32_t indice2 = *((uint16_t*)ptr2) + 1;
|
||||||
indice0 = *((uint16_t*)ptr0) + 1;
|
|
||||||
indice1 = *((uint16_t*)ptr1) + 1;
|
|
||||||
indice2 = *((uint16_t*)ptr2) + 1;
|
|
||||||
}
|
|
||||||
else if (indexBufferAccessor->getComponentType() == davinci::CT_Uint32)
|
|
||||||
{
|
|
||||||
indice0 = *((uint32_t*)ptr0) + 1;
|
|
||||||
indice1 = *((uint32_t*)ptr1) + 1;
|
|
||||||
indice2 = *((uint32_t*)ptr2) + 1;
|
|
||||||
}
|
|
||||||
else if (indexBufferAccessor->getComponentType() == davinci::CT_Uint8)
|
|
||||||
{
|
|
||||||
indice0 = *((uint8_t*)ptr0) + 1;
|
|
||||||
indice1 = *((uint8_t*)ptr1) + 1;
|
|
||||||
indice2 = *((uint8_t*)ptr2) + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//error
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bHasTex0)
|
if (bHasTex0)
|
||||||
{
|
{
|
||||||
@@ -659,6 +1154,7 @@ bool export_mesh_to_obj(const davinci::Scene& scene)
|
|||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
#include "standard/dvu_standard_material.h"
|
||||||
|
#include "device/dvc_device.h"
|
||||||
|
#include "asset/dvc_material.h"
|
||||||
|
|
||||||
|
DV_UTILS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class PbrGltfMaterial : public davinci::Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PbrGltfMaterial(int32_t id, const char* name) : davinci::Material(id, name)
|
||||||
|
{
|
||||||
|
setVertexShader("dv_standard_shaders.dll", "standard+worldpos+normal+uv0");
|
||||||
|
setFragementShader("dv_standard_shaders.dll", "pbr:gltf");
|
||||||
|
|
||||||
|
registerParam<davinci::TextureInfo>("u_baseColorTextureInfo", {});
|
||||||
|
registerParam<davinci::TextureInfo>("u_metalicRoughnessTextureInfo", {});
|
||||||
|
registerParam<float32_t>("u_metalicFactor", 1.f);
|
||||||
|
registerParam<float32_t>("u_roughnessFactor", 1.f);
|
||||||
|
registerParam<davinci::TextureInfo>("u_normalTextureInfo", {});
|
||||||
|
registerParam<float32_t>("u_normalTextureScale", 1.f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PhongMaterial : public davinci::Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PhongMaterial(int32_t id, const char* name) : davinci::Material(id, name)
|
||||||
|
{
|
||||||
|
setVertexShader("dv_standard_shaders.dll", "standard+worldpos+normal-uv0");
|
||||||
|
setFragementShader("dv_standard_shaders.dll", "classic:phong");
|
||||||
|
|
||||||
|
registerParam<davinci::fVector4>("u_materialColor", davinci::fVector4::GRAY);
|
||||||
|
registerParam<float32_t>("u_specularShininess", 64.f);
|
||||||
|
registerParam<float32_t>("u_specularStrength", 5.f);
|
||||||
|
}
|
||||||
|
virtual bool pickupParam(const davinci::MaterialConstPtr orginalMaterial) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SolidColorMaterial : public davinci::Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SolidColorMaterial(int32_t id, const char* name) : davinci::Material(id, name)
|
||||||
|
{
|
||||||
|
setVertexShader("dv_standard_shaders.dll", "standard-worldpos-normal-uv0");
|
||||||
|
setFragementShader("dv_standard_shaders.dll", "debug:solid_color");
|
||||||
|
|
||||||
|
registerParam<davinci::fVector4>("u_solidColor", davinci::fVector4::WHITE);
|
||||||
|
}
|
||||||
|
virtual bool pickupParam(const davinci::MaterialConstPtr orginalMaterial) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BaseColorTextureMaterial : public davinci::Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseColorTextureMaterial(int32_t id, const char* name) : davinci::Material(id, name)
|
||||||
|
{
|
||||||
|
setVertexShader("dv_standard_shaders.dll", "standard+worldpos-normal+uv0");
|
||||||
|
setFragementShader("dv_standard_shaders.dll", "debug:show_texture");
|
||||||
|
|
||||||
|
registerParam<davinci::TextureInfo>("u_textureInfo", {});
|
||||||
|
}
|
||||||
|
virtual bool pickupParam(const davinci::MaterialConstPtr orginalMaterial) override
|
||||||
|
{
|
||||||
|
davinci::TextureInfo baseColorTextureInfo;
|
||||||
|
if (!(orginalMaterial->getParam("u_baseColorTextureInfo", baseColorTextureInfo)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->setParam("u_textureInfo", baseColorTextureInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NormalTextureMaterial : public davinci::Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NormalTextureMaterial(int32_t id, const char* name) : davinci::Material(id, name)
|
||||||
|
{
|
||||||
|
setVertexShader("dv_standard_shaders.dll", "standard+worldpos-normal+uv0");
|
||||||
|
setFragementShader("dv_standard_shaders.dll", "debug:show_texture");
|
||||||
|
|
||||||
|
registerParam<davinci::TextureInfo>("u_textureInfo", {});
|
||||||
|
}
|
||||||
|
virtual bool pickupParam(const davinci::MaterialConstPtr orginalMaterial) override
|
||||||
|
{
|
||||||
|
davinci::TextureInfo normalTextureInfo;
|
||||||
|
if (!(orginalMaterial->getParam("u_normalTextureInfo", normalTextureInfo)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->setParam("u_textureInfo", normalTextureInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextureCoordinates0Material : public davinci::Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextureCoordinates0Material(int32_t id, const char* name) : davinci::Material(id, name)
|
||||||
|
{
|
||||||
|
setVertexShader("dv_standard_shaders.dll", "standard+worldpos-normal+uv0");
|
||||||
|
setFragementShader("dv_standard_shaders.dll", "debug:texture_coordinates");
|
||||||
|
|
||||||
|
registerParam<int32_t>("u_texCoord", 0);
|
||||||
|
}
|
||||||
|
virtual bool pickupParam(const davinci::MaterialConstPtr orginalMaterial) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GeometryNormalMaterial : public davinci::Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeometryNormalMaterial(int32_t id, const char* name) : davinci::Material(id, name)
|
||||||
|
{
|
||||||
|
setVertexShader("dv_standard_shaders.dll", "standard+worldpos+normal-uv0");
|
||||||
|
setFragementShader("dv_standard_shaders.dll", "debug:geometry_normal");
|
||||||
|
}
|
||||||
|
virtual bool pickupParam(const davinci::MaterialConstPtr orginalMaterial) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
davinci::MaterialPtr create_standard_material(davinci::Device* device, const char* name)
|
||||||
|
{
|
||||||
|
if(strcmp(name, "pbr:gltf")==0)
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr materialPtr = device->newMaterialAsset<PbrGltfMaterial>(name);
|
||||||
|
return materialPtr;
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "classic:phong")==0)
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr materialPtr = device->newMaterialAsset<PhongMaterial>(name);
|
||||||
|
return materialPtr;
|
||||||
|
}
|
||||||
|
else if(strcmp(name, "debug:solid_color")==0)
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr materialPtr = device->newMaterialAsset<SolidColorMaterial>(name);
|
||||||
|
return materialPtr;
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "debug:base_color_texture")==0)
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr materialPtr = device->newMaterialAsset<BaseColorTextureMaterial>(name);
|
||||||
|
return materialPtr;
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "debug:normal_texture")==0)
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr materialPtr = device->newMaterialAsset<NormalTextureMaterial>(name);
|
||||||
|
return materialPtr;
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "debug:texture_coordinates_0")==0)
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr materialPtr = device->newMaterialAsset<TextureCoordinates0Material>(name);
|
||||||
|
return materialPtr;
|
||||||
|
}
|
||||||
|
else if (strcmp(name, "debug:geometry_normal")==0)
|
||||||
|
{
|
||||||
|
davinci::MaterialPtr materialPtr = device->newMaterialAsset<GeometryNormalMaterial>(name);
|
||||||
|
return materialPtr;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DV_UTILS_END_NAMESPACE
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user