Added ability to store position, normal, tangent, and uv vertex attributes using GL_SHORT to reduce memory consumption and bandwidth.
Now taking advantage of GL_EXT_discard_framebuffer to reduce extraneous memory copy operations in the PowerVR driver Implemented native support for Maya's extended scene graph node attributes (pre-transform, post-transform, pivot sets, scale compensation) Debugging of broken skinned mesh renderer in progress
This commit is contained in:
@@ -1547,7 +1547,7 @@ void KRAudioManager::startFrame(float deltaTime)
|
|||||||
// apply minimum-cutoff so that we don't waste cycles processing very quiet / distant sound sources
|
// apply minimum-cutoff so that we don't waste cycles processing very quiet / distant sound sources
|
||||||
gain = KRMAX(gain - KRENGINE_AUDIO_CUTOFF, 0.0f) / (1.0f - KRENGINE_AUDIO_CUTOFF);
|
gain = KRMAX(gain - KRENGINE_AUDIO_CUTOFF, 0.0f) / (1.0f - KRENGINE_AUDIO_CUTOFF);
|
||||||
|
|
||||||
if(gain > 0.0f /*|| true*/) { // FINDME, HACK! "true" added to prevent squelching of audio sources that are contributing to reverb
|
if(gain > 0.0f) {
|
||||||
|
|
||||||
KRVector3 source_listener_space = KRVector3(
|
KRVector3 source_listener_space = KRVector3(
|
||||||
KRVector3::Dot(listener_right, diff),
|
KRVector3::Dot(listener_right, diff),
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
KRBone::KRBone(KRScene &scene, std::string name) : KRNode(scene, name)
|
KRBone::KRBone(KRScene &scene, std::string name) : KRNode(scene, name)
|
||||||
{
|
{
|
||||||
|
setScaleCompensation(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
KRBone::~KRBone()
|
KRBone::~KRBone()
|
||||||
@@ -32,23 +32,23 @@ tinyxml2::XMLElement *KRBone::saveXML( tinyxml2::XMLNode *parent)
|
|||||||
void KRBone::loadXML(tinyxml2::XMLElement *e)
|
void KRBone::loadXML(tinyxml2::XMLElement *e)
|
||||||
{
|
{
|
||||||
KRNode::loadXML(e);
|
KRNode::loadXML(e);
|
||||||
|
setScaleCompensation(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KRAABB KRBone::getBounds() {
|
||||||
|
return KRAABB(-KRVector3::One(), KRVector3::One(), getModelMatrix()); // Only required for bone debug visualization
|
||||||
|
}
|
||||||
|
|
||||||
void KRBone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
|
void KRBone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass)
|
||||||
{
|
{
|
||||||
|
|
||||||
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);
|
KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass);
|
||||||
|
|
||||||
bool bVisualize = false;
|
bool bVisualize = pCamera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES;
|
||||||
|
|
||||||
if(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) {
|
if(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) {
|
||||||
KRMat4 sphereModelMatrix = getModelMatrix();
|
KRMat4 sphereModelMatrix = getModelMatrix();
|
||||||
|
|
||||||
KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
|
||||||
|
|
||||||
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass)) {
|
|
||||||
|
|
||||||
// Enable additive blending
|
// Enable additive blending
|
||||||
GLDEBUG(glEnable(GL_BLEND));
|
GLDEBUG(glEnable(GL_BLEND));
|
||||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
|
||||||
@@ -57,10 +57,12 @@ void KRBone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights
|
|||||||
// Disable z-buffer write
|
// Disable z-buffer write
|
||||||
GLDEBUG(glDepthMask(GL_FALSE));
|
GLDEBUG(glDepthMask(GL_FALSE));
|
||||||
|
|
||||||
// Enable z-buffer test
|
// Disable z-buffer test
|
||||||
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||||
GLDEBUG(glDepthFunc(GL_LEQUAL));
|
|
||||||
GLDEBUG(glDepthRangef(0.0, 1.0));
|
KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
|
||||||
|
|
||||||
|
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass)) {
|
||||||
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
|
std::vector<KRMesh *> sphereModels = getContext().getModelManager()->getModel("__sphere");
|
||||||
if(sphereModels.size()) {
|
if(sphereModels.size()) {
|
||||||
for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) {
|
for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) {
|
||||||
@@ -68,9 +70,17 @@ void KRBone::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Enable alpha blending
|
// Enable alpha blending
|
||||||
GLDEBUG(glEnable(GL_BLEND));
|
GLDEBUG(glEnable(GL_BLEND));
|
||||||
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
||||||
}
|
|
||||||
|
// Enable z-buffer test
|
||||||
|
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
||||||
|
GLDEBUG(glDepthFunc(GL_LEQUAL));
|
||||||
|
GLDEBUG(glDepthRangef(0.0, 1.0));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
virtual std::string getElementName();
|
virtual std::string getElementName();
|
||||||
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
|
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
|
||||||
virtual void loadXML(tinyxml2::XMLElement *e);
|
virtual void loadXML(tinyxml2::XMLElement *e);
|
||||||
|
virtual KRAABB getBounds();
|
||||||
|
|
||||||
void render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
void render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,16 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
|
|||||||
|
|
||||||
// Set render target
|
// Set render target
|
||||||
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer));
|
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer));
|
||||||
|
|
||||||
|
|
||||||
|
#if GL_EXT_discard_framebuffer
|
||||||
|
GLenum attachments[2] = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0};
|
||||||
|
GLDEBUG(glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enable z-buffer write
|
||||||
|
GLDEBUG(glDepthMask(GL_TRUE));
|
||||||
|
|
||||||
GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
|
GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
GLDEBUG(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
GLDEBUG(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||||
|
|
||||||
@@ -121,9 +131,6 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
|
|||||||
GLDEBUG(glCullFace(GL_BACK));
|
GLDEBUG(glCullFace(GL_BACK));
|
||||||
GLDEBUG(glEnable(GL_CULL_FACE));
|
GLDEBUG(glEnable(GL_CULL_FACE));
|
||||||
|
|
||||||
// Enable z-buffer write
|
|
||||||
GLDEBUG(glDepthMask(GL_TRUE));
|
|
||||||
|
|
||||||
// Enable z-buffer test
|
// Enable z-buffer test
|
||||||
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
||||||
GLDEBUG(glDepthFunc(GL_LEQUAL));
|
GLDEBUG(glDepthFunc(GL_LEQUAL));
|
||||||
@@ -229,15 +236,23 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
|
|||||||
GLDEBUG(glDisable(GL_BLEND));
|
GLDEBUG(glDisable(GL_BLEND));
|
||||||
|
|
||||||
GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
|
GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
// Enable z-buffer write
|
||||||
|
GLDEBUG(glDepthMask(GL_TRUE));
|
||||||
|
|
||||||
|
|
||||||
|
#if GL_EXT_discard_framebuffer
|
||||||
|
GLenum attachments[2] = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0};
|
||||||
|
GLDEBUG(glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments));
|
||||||
|
GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT));
|
||||||
|
#else
|
||||||
GLDEBUG(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
GLDEBUG(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Enable backface culling
|
// Enable backface culling
|
||||||
GLDEBUG(glCullFace(GL_BACK));
|
GLDEBUG(glCullFace(GL_BACK));
|
||||||
GLDEBUG(glEnable(GL_CULL_FACE));
|
GLDEBUG(glEnable(GL_CULL_FACE));
|
||||||
|
|
||||||
// Enable z-buffer write
|
|
||||||
GLDEBUG(glDepthMask(GL_TRUE));
|
|
||||||
|
|
||||||
// Enable z-buffer test
|
// Enable z-buffer test
|
||||||
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
GLDEBUG(glEnable(GL_DEPTH_TEST));
|
||||||
@@ -282,7 +297,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
|
|||||||
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture);
|
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture);
|
||||||
|
|
||||||
// Render a full screen quad
|
// Render a full screen quad
|
||||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,7 +454,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
|
|||||||
|
|
||||||
KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, true, false, false, false, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true);
|
||||||
for(unordered_map<KRAABB, int>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
|
for(unordered_map<KRAABB, int>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
|
||||||
KRMat4 matModel = KRMat4();
|
KRMat4 matModel = KRMat4();
|
||||||
matModel.scale((*itr).first.size() * 0.5f);
|
matModel.scale((*itr).first.size() * 0.5f);
|
||||||
@@ -465,6 +480,12 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
|
|||||||
m_pContext->getModelManager()->unbindVBO();
|
m_pContext->getModelManager()->unbindVBO();
|
||||||
|
|
||||||
GL_POP_GROUP_MARKER;
|
GL_POP_GROUP_MARKER;
|
||||||
|
|
||||||
|
|
||||||
|
#if GL_EXT_discard_framebuffer
|
||||||
|
GLenum attachments[2] = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0};
|
||||||
|
GLDEBUG(glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -665,7 +686,7 @@ void KRCamera::renderPost()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update attribute values.
|
// Update attribute values.
|
||||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
|
||||||
|
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||||
|
|
||||||
@@ -687,7 +708,7 @@ void KRCamera::renderPost()
|
|||||||
// viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0);
|
// viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0);
|
||||||
// getContext().getShaderManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
// getContext().getShaderManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT);
|
||||||
// m_pContext->getTextureManager()->selectTexture(1, NULL);
|
// m_pContext->getTextureManager()->selectTexture(1, NULL);
|
||||||
// m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, true);
|
// m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
|
||||||
// m_pContext->getTextureManager()->_setActiveTexture(0);
|
// m_pContext->getTextureManager()->_setActiveTexture(0);
|
||||||
// GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
|
// GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow]));
|
||||||
//#if GL_EXT_shadow_samplers
|
//#if GL_EXT_shadow_samplers
|
||||||
@@ -854,7 +875,7 @@ void KRCamera::renderPost()
|
|||||||
m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"));
|
m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font"));
|
||||||
|
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, true, false, false, true, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true);
|
||||||
|
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count));
|
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count));
|
||||||
|
|
||||||
@@ -1048,6 +1069,9 @@ std::string KRCamera::getDebugText()
|
|||||||
case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_COLLIDERS:
|
case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_COLLIDERS:
|
||||||
stream << "Collider Visualization";
|
stream << "Collider Visualization";
|
||||||
break;
|
break;
|
||||||
|
case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES:
|
||||||
|
stream << "Bone Visualization";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,6 @@ std::string KRDirectionalLight::getElementName() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KRVector3 KRDirectionalLight::getWorldLightDirection() {
|
KRVector3 KRDirectionalLight::getWorldLightDirection() {
|
||||||
const GLfloat PI = 3.14159265;
|
|
||||||
const GLfloat d2r = PI * 2 / 360;
|
|
||||||
|
|
||||||
KRVector3 world_rotation = getWorldRotation();
|
KRVector3 world_rotation = getWorldRotation();
|
||||||
KRVector3 light_rotation = KRVector3(0.0, 0.0, 1.0);
|
KRVector3 light_rotation = KRVector3(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
@@ -40,7 +37,7 @@ KRVector3 KRDirectionalLight::getWorldLightDirection() {
|
|||||||
m.rotate(world_rotation.x, X_AXIS);
|
m.rotate(world_rotation.x, X_AXIS);
|
||||||
m.rotate(world_rotation.y, Y_AXIS);
|
m.rotate(world_rotation.y, Y_AXIS);
|
||||||
m.rotate(world_rotation.z, Z_AXIS);
|
m.rotate(world_rotation.z, Z_AXIS);
|
||||||
// m.rotate(-90.0 * d2r, Y_AXIS);
|
|
||||||
KRVector3 light_direction = KRMat4::Dot(m, light_rotation);
|
KRVector3 light_direction = KRMat4::Dot(m, light_rotation);
|
||||||
return light_direction;
|
return light_direction;
|
||||||
}
|
}
|
||||||
@@ -130,7 +127,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &
|
|||||||
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
// Render a full screen quad
|
// Render a full screen quad
|
||||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ float const D2R = PI * 2 / 360;
|
|||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/signals2/mutex.hpp>
|
#include <boost/signals2/mutex.hpp>
|
||||||
|
|
||||||
|
#include "tinyxml2.h"
|
||||||
|
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ bool KRLODGroup::getLODVisibility(const KRViewport &viewport)
|
|||||||
if(m_min_distance == 0 && m_max_distance == 0) {
|
if(m_min_distance == 0 && m_max_distance == 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// return (m_max_distance == 0); // FINDME, HACK - Test code to enable only the lowest LOD group
|
|
||||||
float lod_bias = viewport.getLODBias();
|
float lod_bias = viewport.getLODBias();
|
||||||
lod_bias = pow(2.0f, -lod_bias);
|
lod_bias = pow(2.0f, -lod_bias);
|
||||||
|
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
|
|||||||
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero()));
|
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero()));
|
||||||
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size);
|
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size);
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, true, false, false, true, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true);
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
|
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,7 +266,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
|
|||||||
pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing));
|
pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing));
|
||||||
pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f));
|
pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f));
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRMeshManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRMeshManager::VolumetricLightingVertexData), NULL, 0, true, false, false, false, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRMeshManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRMeshManager::VolumetricLightingVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true);
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
|
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,7 +339,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_light
|
|||||||
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) {
|
if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) {
|
||||||
pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize);
|
pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize);
|
||||||
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture);
|
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture);
|
||||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class KRMat4 {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
float c[16];
|
float c[16]; // Matrix components, in column-major order
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -240,6 +240,10 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
|
|||||||
m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str());
|
m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bones.size() > 0) {
|
||||||
|
bSameMaterial = false; // FINDME, HACK! - This is test code
|
||||||
|
}
|
||||||
|
|
||||||
if(!bSameMaterial) {
|
if(!bSameMaterial) {
|
||||||
KRVector2 default_scale = KRVector2(1.0f, 1.0f);
|
KRVector2 default_scale = KRVector2(1.0f, 1.0f);
|
||||||
KRVector2 default_offset = KRVector2(0.0f, 0.0f);
|
KRVector2 default_offset = KRVector2(0.0f, 0.0f);
|
||||||
@@ -283,7 +287,9 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
|
|||||||
//printf("%s - delta translation: %.4f %.4f %.4f\n", bone->getName().c_str(), translation.x - initialTranslation.x, translation.y - initialTranslation.y, translation.z - initialTranslation.z);
|
//printf("%s - delta translation: %.4f %.4f %.4f\n", bone->getName().c_str(), translation.x - initialTranslation.x, translation.y - initialTranslation.y, translation.z - initialTranslation.z);
|
||||||
// printf("%s - delta scale: %.4f %.4f %.4f\n", bone->getName().c_str(), scale.x - initialScale.x, scale.y - initialScale.y, scale.z - initialScale.z);
|
// printf("%s - delta scale: %.4f %.4f %.4f\n", bone->getName().c_str(), scale.x - initialScale.x, scale.y - initialScale.y, scale.z - initialScale.z);
|
||||||
|
|
||||||
KRMat4 t = bone->getInverseBindPoseMatrix() * bone->getModelMatrix();
|
KRMat4 model_mat = bone->getActivePoseMatrix();
|
||||||
|
KRMat4 inv_bind_mat = bone->getInverseBindPoseMatrix();
|
||||||
|
KRMat4 t = /*KRMat4::Invert(matModel) * */(inv_bind_mat * model_mat);
|
||||||
for(int i=0; i < 16; i++) {
|
for(int i=0; i < 16; i++) {
|
||||||
*bone_mat_component++ = t[i];
|
*bone_mat_component++ = t[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st
|
|||||||
int start_index_offset, start_vertex_offset, index_count, vertex_count;
|
int start_index_offset, start_vertex_offset, index_count, vertex_count;
|
||||||
getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count);
|
getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count);
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES), has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS), true);
|
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, pHeader->vertex_attrib_flags, true);
|
||||||
|
|
||||||
int vertex_draw_count = cVertexes;
|
int vertex_draw_count = cVertexes;
|
||||||
if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset;
|
if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset;
|
||||||
@@ -297,7 +297,7 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st
|
|||||||
assert(cBufferVertexes <= 65535);
|
assert(cBufferVertexes <= 65535);
|
||||||
|
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES), has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS), true);
|
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, pHeader->vertex_attrib_flags, true);
|
||||||
|
|
||||||
|
|
||||||
if(iVertex + cVertexes >= MAX_VBO_SIZE) {
|
if(iVertex + cVertexes >= MAX_VBO_SIZE) {
|
||||||
@@ -351,23 +351,85 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector<std::p
|
|||||||
|
|
||||||
clearData();
|
clearData();
|
||||||
|
|
||||||
|
// TODO, FINDME - These values should be passed as a parameter and set by GUI flags
|
||||||
|
bool use_short_vertexes = false;
|
||||||
|
bool use_short_normals = true;
|
||||||
|
bool use_short_tangents = true;
|
||||||
|
bool use_short_uva = true;
|
||||||
|
bool use_short_uvb = true;
|
||||||
|
|
||||||
|
if(use_short_vertexes) {
|
||||||
|
for(std::vector<KRVector3>::iterator itr=vertices.begin(); itr != vertices.end(); itr++) {
|
||||||
|
if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f || fabsf((*itr).z) > 1.0f) {
|
||||||
|
use_short_vertexes = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(use_short_normals) {
|
||||||
|
for(std::vector<KRVector3>::iterator itr=normals.begin(); itr != normals.end(); itr++) {
|
||||||
|
(*itr).normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(use_short_tangents) {
|
||||||
|
for(std::vector<KRVector3>::iterator itr=tangents.begin(); itr != tangents.end(); itr++) {
|
||||||
|
(*itr).normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(use_short_uva) {
|
||||||
|
for(std::vector<KRVector2>::iterator itr=uva.begin(); itr != uva.end(); itr++) {
|
||||||
|
if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) {
|
||||||
|
use_short_uva = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(use_short_uvb) {
|
||||||
|
for(std::vector<KRVector2>::iterator itr=uvb.begin(); itr != uvb.end(); itr++) {
|
||||||
|
if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) {
|
||||||
|
use_short_uvb = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__int32_t vertex_attrib_flags = 0;
|
__int32_t vertex_attrib_flags = 0;
|
||||||
if(vertices.size()) {
|
if(vertices.size()) {
|
||||||
|
if(use_short_vertexes) {
|
||||||
|
vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX_SHORT);
|
||||||
|
} else {
|
||||||
vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX);
|
vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(normals.size() || calculate_normals) {
|
if(normals.size() || calculate_normals) {
|
||||||
|
if(use_short_normals) {
|
||||||
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL_SHORT);
|
||||||
|
} else {
|
||||||
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL);
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(tangents.size() || calculate_tangents) {
|
if(tangents.size() || calculate_tangents) {
|
||||||
|
if(use_short_tangents) {
|
||||||
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT_SHORT);
|
||||||
|
} else {
|
||||||
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT);
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(uva.size()) {
|
if(uva.size()) {
|
||||||
|
if(use_short_uva) {
|
||||||
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA_SHORT);
|
||||||
|
} else {
|
||||||
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA);
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(uvb.size()) {
|
if(uvb.size()) {
|
||||||
|
if(use_short_uvb) {
|
||||||
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB_SHORT);
|
||||||
|
} else {
|
||||||
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB);
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(bone_names.size()) {
|
if(bone_names.size()) {
|
||||||
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_BONEINDEXES) + (1 << KRENGINE_ATTRIB_BONEWEIGHTS);
|
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_BONEINDEXES) + (1 << KRENGINE_ATTRIB_BONEWEIGHTS);
|
||||||
}
|
}
|
||||||
@@ -557,7 +619,13 @@ bool KRMesh::lod_sort_predicate(const KRMesh *m1, const KRMesh *m2)
|
|||||||
|
|
||||||
bool KRMesh::has_vertex_attribute(vertex_attrib_t attribute_type) const
|
bool KRMesh::has_vertex_attribute(vertex_attrib_t attribute_type) const
|
||||||
{
|
{
|
||||||
return (getHeader()->vertex_attrib_flags & (1 << attribute_type)) != 0;
|
//return (getHeader()->vertex_attrib_flags & (1 << attribute_type)) != 0;
|
||||||
|
return has_vertex_attribute(getHeader()->vertex_attrib_flags, attribute_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KRMesh::has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attribute_type)
|
||||||
|
{
|
||||||
|
return (vertex_attrib_flags & (1 << attribute_type)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KRMesh::pack_header *KRMesh::getHeader() const
|
KRMesh::pack_header *KRMesh::getHeader() const
|
||||||
@@ -610,7 +678,10 @@ int KRMesh::getVertexCount(int submesh) const
|
|||||||
|
|
||||||
KRVector3 KRMesh::getVertexPosition(int index) const
|
KRVector3 KRMesh::getVertexPosition(int index) const
|
||||||
{
|
{
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) {
|
||||||
|
short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX_SHORT]);
|
||||||
|
return KRVector3((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f);
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) {
|
||||||
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]));
|
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]));
|
||||||
} else {
|
} else {
|
||||||
return KRVector3::Zero();
|
return KRVector3::Zero();
|
||||||
@@ -619,7 +690,10 @@ KRVector3 KRMesh::getVertexPosition(int index) const
|
|||||||
|
|
||||||
KRVector3 KRMesh::getVertexNormal(int index) const
|
KRVector3 KRMesh::getVertexNormal(int index) const
|
||||||
{
|
{
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) {
|
||||||
|
short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL_SHORT]);
|
||||||
|
return KRVector3((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f);
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) {
|
||||||
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]));
|
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]));
|
||||||
} else {
|
} else {
|
||||||
return KRVector3::Zero();
|
return KRVector3::Zero();
|
||||||
@@ -628,7 +702,10 @@ KRVector3 KRMesh::getVertexNormal(int index) const
|
|||||||
|
|
||||||
KRVector3 KRMesh::getVertexTangent(int index) const
|
KRVector3 KRMesh::getVertexTangent(int index) const
|
||||||
{
|
{
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) {
|
||||||
|
short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT_SHORT]);
|
||||||
|
return KRVector3((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f);
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) {
|
||||||
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]));
|
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]));
|
||||||
} else {
|
} else {
|
||||||
return KRVector3::Zero();
|
return KRVector3::Zero();
|
||||||
@@ -637,7 +714,10 @@ KRVector3 KRMesh::getVertexTangent(int index) const
|
|||||||
|
|
||||||
KRVector2 KRMesh::getVertexUVA(int index) const
|
KRVector2 KRMesh::getVertexUVA(int index) const
|
||||||
{
|
{
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) {
|
||||||
|
short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA_SHORT]);
|
||||||
|
return KRVector2((float)v[0] / 32767.0f, (float)v[1] / 32767.0f);
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) {
|
||||||
return KRVector2((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]));
|
return KRVector2((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]));
|
||||||
} else {
|
} else {
|
||||||
return KRVector2::Zero();
|
return KRVector2::Zero();
|
||||||
@@ -646,7 +726,10 @@ KRVector2 KRMesh::getVertexUVA(int index) const
|
|||||||
|
|
||||||
KRVector2 KRMesh::getVertexUVB(int index) const
|
KRVector2 KRMesh::getVertexUVB(int index) const
|
||||||
{
|
{
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) {
|
||||||
|
short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB_SHORT]);
|
||||||
|
return KRVector2((float)v[0] / 32767.0f, (float)v[1] / 32767.0f);
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) {
|
||||||
return KRVector2((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]));
|
return KRVector2((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]));
|
||||||
} else {
|
} else {
|
||||||
return KRVector2::Zero();
|
return KRVector2::Zero();
|
||||||
@@ -655,41 +738,74 @@ KRVector2 KRMesh::getVertexUVB(int index) const
|
|||||||
|
|
||||||
void KRMesh::setVertexPosition(int index, const KRVector3 &v)
|
void KRMesh::setVertexPosition(int index, const KRVector3 &v)
|
||||||
{
|
{
|
||||||
|
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) {
|
||||||
|
short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX_SHORT]);
|
||||||
|
vert[0] = v.x * 32767.0f;
|
||||||
|
vert[1] = v.y * 32767.0f;
|
||||||
|
vert[2] = v.z * 32767.0f;
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) {
|
||||||
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]);
|
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]);
|
||||||
vert[0] = v.x;
|
vert[0] = v.x;
|
||||||
vert[1] = v.y;
|
vert[1] = v.y;
|
||||||
vert[2] = v.z;
|
vert[2] = v.z;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KRMesh::setVertexNormal(int index, const KRVector3 &v)
|
void KRMesh::setVertexNormal(int index, const KRVector3 &v)
|
||||||
{
|
{
|
||||||
|
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) {
|
||||||
|
short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL_SHORT]);
|
||||||
|
vert[0] = v.x * 32767.0f;
|
||||||
|
vert[1] = v.y * 32767.0f;
|
||||||
|
vert[2] = v.z * 32767.0f;
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) {
|
||||||
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]);
|
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]);
|
||||||
vert[0] = v.x;
|
vert[0] = v.x;
|
||||||
vert[1] = v.y;
|
vert[1] = v.y;
|
||||||
vert[2] = v.z;
|
vert[2] = v.z;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KRMesh::setVertexTangent(int index, const KRVector3 & v)
|
void KRMesh::setVertexTangent(int index, const KRVector3 & v)
|
||||||
{
|
{
|
||||||
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) {
|
||||||
|
short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT_SHORT]);
|
||||||
|
vert[0] = v.x * 32767.0f;
|
||||||
|
vert[1] = v.y * 32767.0f;
|
||||||
|
vert[2] = v.z * 32767.0f;
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) {
|
||||||
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]);
|
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]);
|
||||||
vert[0] = v.x;
|
vert[0] = v.x;
|
||||||
vert[1] = v.y;
|
vert[1] = v.y;
|
||||||
vert[2] = v.z;
|
vert[2] = v.z;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KRMesh::setVertexUVA(int index, const KRVector2 &v)
|
void KRMesh::setVertexUVA(int index, const KRVector2 &v)
|
||||||
{
|
{
|
||||||
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) {
|
||||||
|
short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA_SHORT]);
|
||||||
|
vert[0] = v.x * 32767.0f;
|
||||||
|
vert[1] = v.y * 32767.0f;
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) {
|
||||||
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]);
|
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]);
|
||||||
vert[0] = v.x;
|
vert[0] = v.x;
|
||||||
vert[1] = v.y;
|
vert[1] = v.y;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KRMesh::setVertexUVB(int index, const KRVector2 &v)
|
void KRMesh::setVertexUVB(int index, const KRVector2 &v)
|
||||||
{
|
{
|
||||||
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) {
|
||||||
|
short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB_SHORT]);
|
||||||
|
vert[0] = v.x * 32767.0f;
|
||||||
|
vert[1] = v.y * 32767.0f;
|
||||||
|
} else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) {
|
||||||
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]);
|
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]);
|
||||||
vert[0] = v.x;
|
vert[0] = v.x;
|
||||||
vert[1] = v.y;
|
vert[1] = v.y;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int KRMesh::getBoneIndex(int index, int weight_index) const
|
int KRMesh::getBoneIndex(int index, int weight_index) const
|
||||||
@@ -719,27 +835,42 @@ void KRMesh::setBoneWeight(int index, int weight_index, float bone_weight)
|
|||||||
size_t KRMesh::VertexSizeForAttributes(__int32_t vertex_attrib_flags)
|
size_t KRMesh::VertexSizeForAttributes(__int32_t vertex_attrib_flags)
|
||||||
{
|
{
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_VERTEX)) {
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_VERTEX)) {
|
||||||
data_size += sizeof(float) * 3;
|
data_size += sizeof(float) * 3;
|
||||||
}
|
}
|
||||||
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_NORMAL)) {
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_NORMAL)) {
|
||||||
data_size += sizeof(float) * 3;
|
data_size += sizeof(float) * 3;
|
||||||
}
|
}
|
||||||
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TANGENT)) {
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TANGENT)) {
|
||||||
data_size += sizeof(float) * 3;
|
data_size += sizeof(float) * 3;
|
||||||
}
|
}
|
||||||
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TEXUVA)) {
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVA)) {
|
||||||
data_size += sizeof(float) * 2;
|
data_size += sizeof(float) * 2;
|
||||||
}
|
}
|
||||||
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TEXUVB)) {
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVB)) {
|
||||||
data_size += sizeof(float) * 2;
|
data_size += sizeof(float) * 2;
|
||||||
}
|
}
|
||||||
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_BONEINDEXES)) {
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_BONEINDEXES)) {
|
||||||
data_size += 4; // 4 bytes
|
data_size += 4; // 4 bytes
|
||||||
}
|
}
|
||||||
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_BONEWEIGHTS)) {
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_BONEWEIGHTS)) {
|
||||||
data_size += sizeof(float) * 4;
|
data_size += sizeof(float) * 4;
|
||||||
}
|
}
|
||||||
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_VERTEX_SHORT)) {
|
||||||
|
data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute...
|
||||||
|
}
|
||||||
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_NORMAL_SHORT)) {
|
||||||
|
data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute...
|
||||||
|
}
|
||||||
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TANGENT_SHORT)) {
|
||||||
|
data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute...
|
||||||
|
}
|
||||||
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVA_SHORT)) {
|
||||||
|
data_size += sizeof(short) * 2;
|
||||||
|
}
|
||||||
|
if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVB_SHORT)) {
|
||||||
|
data_size += sizeof(short) * 2;
|
||||||
|
}
|
||||||
return data_size;
|
return data_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -929,6 +1060,9 @@ bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitin
|
|||||||
|
|
||||||
void KRMesh::convertToIndexed()
|
void KRMesh::convertToIndexed()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
char *szKey = new char[m_vertex_size * 2 + 1];
|
||||||
|
|
||||||
// Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU
|
// Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU
|
||||||
std::vector<__uint16_t> vertex_indexes;
|
std::vector<__uint16_t> vertex_indexes;
|
||||||
std::vector<std::pair<int, int> > vertex_index_bases;
|
std::vector<std::pair<int, int> > vertex_index_bases;
|
||||||
@@ -975,12 +1109,13 @@ void KRMesh::convertToIndexed()
|
|||||||
|
|
||||||
while(vertexes_remaining) {
|
while(vertexes_remaining) {
|
||||||
|
|
||||||
std::map<std::pair<std::vector<float>, std::vector<int> >, int> prev_indexes = std::map<std::pair<std::vector<float>, std::vector<int> >, int>();
|
//typedef std::pair<std::vector<float>, std::vector<int> > vertex_key_t;
|
||||||
|
typedef std::string vertex_key_t;
|
||||||
|
|
||||||
|
unordered_map<vertex_key_t, int> prev_indexes = unordered_map<vertex_key_t, int>();
|
||||||
|
|
||||||
for(int i=0; i < vertex_count; i++) {
|
for(int i=0; i < vertex_count; i++) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
KRVector3 vertex_position = getVertexPosition(source_index);
|
KRVector3 vertex_position = getVertexPosition(source_index);
|
||||||
KRVector2 vertex_uva = getVertexUVA(source_index);
|
KRVector2 vertex_uva = getVertexUVA(source_index);
|
||||||
KRVector2 vertex_uvb = getVertexUVB(source_index);
|
KRVector2 vertex_uvb = getVertexUVB(source_index);
|
||||||
@@ -1001,26 +1136,40 @@ void KRMesh::convertToIndexed()
|
|||||||
vertex_bone_weights.push_back(getBoneWeight(source_index, 3));
|
vertex_bone_weights.push_back(getBoneWeight(source_index, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::vector<float>, std::vector<int> > vertex_key; // = std::make_pair(std::vector<float>(), std::vector<int>());
|
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) {
|
|
||||||
|
unsigned char *vertex_data = (unsigned char *)getVertexData(source_index);
|
||||||
|
for(int b=0; b < m_vertex_size; b++) {
|
||||||
|
const char *szHex = "0123456789ABCDEF";
|
||||||
|
szKey[b*2] = szHex[vertex_data[b] & 0x0f];
|
||||||
|
szKey[b*2+1] = szHex[((vertex_data[b] & 0xf0) >> 4)];
|
||||||
|
}
|
||||||
|
szKey[m_vertex_size * 2] = '\0';
|
||||||
|
|
||||||
|
vertex_key_t vertex_key = szKey;
|
||||||
|
/*
|
||||||
|
|
||||||
|
vertex_key_t vertex_key = std::make_pair(std::vector<float>(), std::vector<int>());
|
||||||
|
|
||||||
|
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) {
|
||||||
vertex_key.first.push_back(vertex_position.x);
|
vertex_key.first.push_back(vertex_position.x);
|
||||||
vertex_key.first.push_back(vertex_position.y);
|
vertex_key.first.push_back(vertex_position.y);
|
||||||
vertex_key.first.push_back(vertex_position.z);
|
vertex_key.first.push_back(vertex_position.z);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) {
|
||||||
vertex_key.first.push_back(vertex_normal.x);
|
vertex_key.first.push_back(vertex_normal.x);
|
||||||
vertex_key.first.push_back(vertex_normal.y);
|
vertex_key.first.push_back(vertex_normal.y);
|
||||||
vertex_key.first.push_back(vertex_normal.z);
|
vertex_key.first.push_back(vertex_normal.z);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) {
|
||||||
vertex_key.first.push_back(vertex_uva.x);
|
vertex_key.first.push_back(vertex_uva.x);
|
||||||
vertex_key.first.push_back(vertex_uva.y);
|
vertex_key.first.push_back(vertex_uva.y);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) {
|
||||||
vertex_key.first.push_back(vertex_uvb.x);
|
vertex_key.first.push_back(vertex_uvb.x);
|
||||||
vertex_key.first.push_back(vertex_uvb.y);
|
vertex_key.first.push_back(vertex_uvb.y);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) {
|
||||||
vertex_key.first.push_back(vertex_tangent.x);
|
vertex_key.first.push_back(vertex_tangent.x);
|
||||||
vertex_key.first.push_back(vertex_tangent.y);
|
vertex_key.first.push_back(vertex_tangent.y);
|
||||||
vertex_key.first.push_back(vertex_tangent.z);
|
vertex_key.first.push_back(vertex_tangent.z);
|
||||||
@@ -1037,23 +1186,23 @@ void KRMesh::convertToIndexed()
|
|||||||
vertex_key.first.push_back(vertex_bone_weights[2]);
|
vertex_key.first.push_back(vertex_bone_weights[2]);
|
||||||
vertex_key.first.push_back(vertex_bone_weights[3]);
|
vertex_key.first.push_back(vertex_bone_weights[3]);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
int found_index = -1;
|
int found_index = -1;
|
||||||
if(prev_indexes.count(vertex_key) == 0) {
|
if(prev_indexes.count(vertex_key) == 0) {
|
||||||
found_index = vertices.size() - vertex_index_base_start_vertex;
|
found_index = vertices.size() - vertex_index_base_start_vertex;
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) {
|
||||||
vertices.push_back(vertex_position);
|
vertices.push_back(vertex_position);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) {
|
||||||
normals.push_back(vertex_normal);
|
normals.push_back(vertex_normal);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) {
|
||||||
tangents.push_back(vertex_tangent);
|
tangents.push_back(vertex_tangent);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) {
|
||||||
uva.push_back(vertex_uva);
|
uva.push_back(vertex_uva);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) {
|
||||||
uvb.push_back(vertex_uvb);
|
uvb.push_back(vertex_uvb);
|
||||||
}
|
}
|
||||||
if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) {
|
if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) {
|
||||||
@@ -1091,8 +1240,12 @@ void KRMesh::convertToIndexed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete szKey;
|
||||||
|
|
||||||
fprintf(stderr, "Convert to indexed, before: %i after: %i \(%.2f%% saving)\n", getHeader()->vertex_count, vertices.size(), ((float)getHeader()->vertex_count - (float)vertices.size()) / (float)getHeader()->vertex_count * 100.0f);
|
fprintf(stderr, "Convert to indexed, before: %i after: %i \(%.2f%% saving)\n", getHeader()->vertex_count, vertices.size(), ((float)getHeader()->vertex_count - (float)vertices.size()) / (float)getHeader()->vertex_count * 100.0f);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights, KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES, false, false);
|
LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights, KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1228,27 +1381,4 @@ void KRMesh::optimizeIndexes()
|
|||||||
free(new_indices);
|
free(new_indices);
|
||||||
free(vertex_mapping);
|
free(vertex_mapping);
|
||||||
free(new_vertex_data);
|
free(new_vertex_data);
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
|
|
||||||
if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) {
|
|
||||||
|
|
||||||
int cVertexes = pSubmesh->vertex_count;
|
|
||||||
//fprintf(stderr, "start - object: %s material: %s vertices: %i\n", object_name.c_str(), material_name.c_str(), cVertexes);
|
|
||||||
|
|
||||||
__uint16_t *index_data = getIndexData();
|
|
||||||
int submesh_index_group = 0;
|
|
||||||
while(cVertexes > 0) {
|
|
||||||
|
|
||||||
int start_index_offset, start_vertex_offset, index_count, vertex_count;
|
|
||||||
getIndexedRange(iSubmesh, submesh_index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count);
|
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, m_vertex_size * vertex_count, index_data + start_index_offset, index_count * 4, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES), has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS), true);
|
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_SHORT, 0);
|
|
||||||
cVertexes -= index_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ public:
|
|||||||
KRENGINE_ATTRIB_TEXUVB,
|
KRENGINE_ATTRIB_TEXUVB,
|
||||||
KRENGINE_ATTRIB_BONEINDEXES,
|
KRENGINE_ATTRIB_BONEINDEXES,
|
||||||
KRENGINE_ATTRIB_BONEWEIGHTS,
|
KRENGINE_ATTRIB_BONEWEIGHTS,
|
||||||
|
KRENGINE_ATTRIB_VERTEX_SHORT,
|
||||||
|
KRENGINE_ATTRIB_NORMAL_SHORT,
|
||||||
|
KRENGINE_ATTRIB_TANGENT_SHORT,
|
||||||
|
KRENGINE_ATTRIB_TEXUVA_SHORT,
|
||||||
|
KRENGINE_ATTRIB_TEXUVB_SHORT,
|
||||||
KRENGINE_NUM_ATTRIBUTES
|
KRENGINE_NUM_ATTRIBUTES
|
||||||
} vertex_attrib_t;
|
} vertex_attrib_t;
|
||||||
|
|
||||||
@@ -113,25 +118,6 @@ public:
|
|||||||
char szMaterialName[KRENGINE_MAX_NAME_LENGTH];
|
char szMaterialName[KRENGINE_MAX_NAME_LENGTH];
|
||||||
} Submesh;
|
} Submesh;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GLfloat x;
|
|
||||||
GLfloat y;
|
|
||||||
GLfloat z;
|
|
||||||
} KRVector3D;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GLfloat u;
|
|
||||||
GLfloat v;
|
|
||||||
} TexCoord;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
KRVector3D vertex;
|
|
||||||
KRVector3D normal;
|
|
||||||
KRVector3D tangent;
|
|
||||||
TexCoord uva;
|
|
||||||
TexCoord uvb;
|
|
||||||
} VertexData;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
struct { // For Indexed triangles / strips
|
struct { // For Indexed triangles / strips
|
||||||
@@ -154,6 +140,7 @@ public:
|
|||||||
|
|
||||||
static bool lod_sort_predicate(const KRMesh *m1, const KRMesh *m2);
|
static bool lod_sort_predicate(const KRMesh *m1, const KRMesh *m2);
|
||||||
bool has_vertex_attribute(vertex_attrib_t attribute_type) const;
|
bool has_vertex_attribute(vertex_attrib_t attribute_type) const;
|
||||||
|
static bool has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attribute_type);
|
||||||
|
|
||||||
int getSubmeshCount() const;
|
int getSubmeshCount() const;
|
||||||
int getVertexCount(int submesh) const;
|
int getVertexCount(int submesh) const;
|
||||||
|
|||||||
@@ -146,8 +146,7 @@ void KRMeshManager::releaseVBO(GLvoid *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights, bool static_vbo) {
|
void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo) {
|
||||||
|
|
||||||
|
|
||||||
if(m_currentVBO.data != data || m_currentVBO.size != size + index_data_size) {
|
if(m_currentVBO.data != data || m_currentVBO.size != size + index_data_size) {
|
||||||
|
|
||||||
@@ -157,7 +156,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
|
|||||||
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
|
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
|
||||||
#else
|
#else
|
||||||
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
|
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
|
||||||
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights);
|
configureAttribs(vertex_attrib_flags);
|
||||||
if(m_currentVBO.vbo_handle_indexes == -1) {
|
if(m_currentVBO.vbo_handle_indexes == -1) {
|
||||||
GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
} else {
|
} else {
|
||||||
@@ -172,7 +171,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
|
|||||||
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
|
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
|
||||||
#else
|
#else
|
||||||
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
|
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
|
||||||
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights);
|
configureAttribs(vertex_attrib_flags);
|
||||||
if(m_currentVBO.vbo_handle_indexes == -1) {
|
if(m_currentVBO.vbo_handle_indexes == -1) {
|
||||||
GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
} else {
|
} else {
|
||||||
@@ -218,7 +217,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
|
|||||||
GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW));
|
GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW));
|
||||||
m_memoryTransferredThisFrame += size;
|
m_memoryTransferredThisFrame += size;
|
||||||
m_vboMemUsed += size;
|
m_vboMemUsed += size;
|
||||||
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights);
|
configureAttribs(vertex_attrib_flags);
|
||||||
|
|
||||||
m_currentVBO.size = size;
|
m_currentVBO.size = size;
|
||||||
m_currentVBO.data = data;
|
m_currentVBO.data = data;
|
||||||
@@ -238,82 +237,73 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRMeshManager::configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights)
|
void KRMeshManager::configureAttribs(__int32_t attributes)
|
||||||
{
|
{
|
||||||
__int32_t attributes = 0;
|
GLsizei data_size = (GLsizei)KRMesh::VertexSizeForAttributes(attributes);
|
||||||
|
|
||||||
if(enable_vertex) {
|
if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_VERTEX_SHORT)) {
|
||||||
attributes |= (1 << KRMesh::KRENGINE_ATTRIB_VERTEX);
|
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_VERTEX));
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_VERTEX));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_VERTEX_SHORT, attributes))));
|
||||||
|
} else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_VERTEX)) {
|
||||||
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_VERTEX));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_VERTEX, attributes))));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_VERTEX));
|
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_VERTEX));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_normal) {
|
if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_NORMAL_SHORT)) {
|
||||||
attributes |= (1 << KRMesh::KRENGINE_ATTRIB_NORMAL);
|
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_NORMAL));
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_NORMAL));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_NORMAL, 3, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_NORMAL_SHORT, attributes))));
|
||||||
|
} else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_NORMAL)) {
|
||||||
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_NORMAL));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_NORMAL, attributes))));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_NORMAL));
|
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_NORMAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_tangent) {
|
if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TANGENT_SHORT)) {
|
||||||
attributes |= (1 << KRMesh::KRENGINE_ATTRIB_TANGENT);
|
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TANGENT));
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TANGENT));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TANGENT, 3, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TANGENT_SHORT, attributes))));
|
||||||
|
} else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TANGENT)) {
|
||||||
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TANGENT));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TANGENT, attributes))));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TANGENT));
|
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TANGENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_uva) {
|
if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TEXUVA_SHORT)) {
|
||||||
attributes |= (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA);
|
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVA));
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVA));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVA, 2, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVA_SHORT, attributes))));
|
||||||
|
} else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TEXUVA)) {
|
||||||
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVA));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVA, attributes))));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVA));
|
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVA));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_uvb) {
|
if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TEXUVB_SHORT)) {
|
||||||
attributes |= (1 << KRMesh::KRENGINE_ATTRIB_TEXUVB);
|
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVB));
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVB));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVB, 2, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVB_SHORT, attributes))));
|
||||||
|
} else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TEXUVB)) {
|
||||||
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVB));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVB, attributes))));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVB));
|
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVB));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_bone_indexes) {
|
if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_BONEINDEXES)) {
|
||||||
attributes |= (1 << KRMesh::KRENGINE_ATTRIB_BONEINDEXES);
|
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEINDEXES));
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEINDEXES));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_BONEINDEXES, 4, GL_UNSIGNED_BYTE, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_BONEINDEXES, attributes))));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEINDEXES));
|
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEINDEXES));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enable_bone_weights) {
|
if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS)) {
|
||||||
attributes |= (1 << KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS);
|
|
||||||
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS));
|
GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS));
|
||||||
|
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, attributes))));
|
||||||
} else {
|
} else {
|
||||||
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS));
|
GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS));
|
||||||
}
|
}
|
||||||
|
|
||||||
GLsizei data_size = (GLsizei)KRMesh::VertexSizeForAttributes(attributes);
|
|
||||||
|
|
||||||
if(enable_vertex) {
|
|
||||||
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_VERTEX, attributes))));
|
|
||||||
}
|
|
||||||
if(enable_normal) {
|
|
||||||
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_NORMAL, attributes))));
|
|
||||||
}
|
|
||||||
if(enable_tangent) {
|
|
||||||
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TANGENT, attributes))));
|
|
||||||
}
|
|
||||||
if(enable_uva) {
|
|
||||||
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVA, attributes))));
|
|
||||||
}
|
|
||||||
if(enable_uvb) {
|
|
||||||
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVB, attributes))));
|
|
||||||
}
|
|
||||||
if(enable_bone_indexes ) {
|
|
||||||
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_BONEINDEXES, 4, GL_UNSIGNED_BYTE, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_BONEINDEXES, attributes))));
|
|
||||||
}
|
|
||||||
if(enable_bone_weights) {
|
|
||||||
GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, attributes))));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long KRMeshManager::getMemUsed()
|
long KRMeshManager::getMemUsed()
|
||||||
|
|||||||
@@ -59,15 +59,13 @@ public:
|
|||||||
std::vector<std::string> getModelNames();
|
std::vector<std::string> getModelNames();
|
||||||
unordered_multimap<std::string, KRMesh *> &getModels();
|
unordered_multimap<std::string, KRMesh *> &getModels();
|
||||||
|
|
||||||
|
void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo);
|
||||||
void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights, bool static_vbo);
|
|
||||||
void releaseVBO(GLvoid *data);
|
void releaseVBO(GLvoid *data);
|
||||||
void unbindVBO();
|
void unbindVBO();
|
||||||
long getMemUsed();
|
long getMemUsed();
|
||||||
long getMemActive();
|
long getMemActive();
|
||||||
|
|
||||||
void configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights);
|
void configureAttribs(__int32_t attributes);
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GLfloat x;
|
GLfloat x;
|
||||||
|
|||||||
@@ -30,15 +30,22 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
|
|||||||
m_localScale = KRVector3::One();
|
m_localScale = KRVector3::One();
|
||||||
m_localRotation = KRVector3::Zero();
|
m_localRotation = KRVector3::Zero();
|
||||||
m_localTranslation = KRVector3::Zero();
|
m_localTranslation = KRVector3::Zero();
|
||||||
|
m_initialLocalTranslation = m_localTranslation;
|
||||||
|
m_initialLocalScale = m_localScale;
|
||||||
|
m_initialLocalRotation = m_localRotation;
|
||||||
|
|
||||||
m_parentNode = NULL;
|
m_parentNode = NULL;
|
||||||
m_pScene = &scene;
|
m_pScene = &scene;
|
||||||
m_modelMatrixValid = false;
|
m_modelMatrixValid = false;
|
||||||
m_inverseModelMatrixValid = false;
|
m_inverseModelMatrixValid = false;
|
||||||
m_bindPoseMatrixValid = false;
|
m_bindPoseMatrixValid = false;
|
||||||
|
m_activePoseMatrixValid = false;
|
||||||
m_inverseBindPoseMatrixValid = false;
|
m_inverseBindPoseMatrixValid = false;
|
||||||
m_modelMatrix = KRMat4();
|
m_modelMatrix = KRMat4();
|
||||||
m_bindPoseMatrix = KRMat4();
|
m_bindPoseMatrix = KRMat4();
|
||||||
|
m_activePoseMatrix = KRMat4();
|
||||||
m_lod_visible = false;
|
m_lod_visible = false;
|
||||||
|
m_scale_compensation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
KRNode::~KRNode() {
|
KRNode::~KRNode() {
|
||||||
@@ -53,6 +60,19 @@ KRNode::~KRNode() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KRNode::setScaleCompensation(bool scale_compensation)
|
||||||
|
{
|
||||||
|
if(m_scale_compensation != scale_compensation) {
|
||||||
|
m_scale_compensation = scale_compensation;
|
||||||
|
invalidateModelMatrix();
|
||||||
|
invalidateBindPoseMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool KRNode::getScaleCompensation()
|
||||||
|
{
|
||||||
|
return m_scale_compensation;
|
||||||
|
}
|
||||||
|
|
||||||
void KRNode::childDeleted(KRNode *child_node)
|
void KRNode::childDeleted(KRNode *child_node)
|
||||||
{
|
{
|
||||||
m_childNodes.erase(child_node);
|
m_childNodes.erase(child_node);
|
||||||
@@ -75,15 +95,18 @@ tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) {
|
|||||||
tinyxml2::XMLElement *e = doc->NewElement(getElementName().c_str());
|
tinyxml2::XMLElement *e = doc->NewElement(getElementName().c_str());
|
||||||
tinyxml2::XMLNode *n = parent->InsertEndChild(e);
|
tinyxml2::XMLNode *n = parent->InsertEndChild(e);
|
||||||
e->SetAttribute("name", m_name.c_str());
|
e->SetAttribute("name", m_name.c_str());
|
||||||
e->SetAttribute("translate_x", m_localTranslation.x); // TODO - Increase number of digits after the decimal in floating point format (6 -> 12?)
|
m_localTranslation.setXMLAttribute("translate", e);
|
||||||
e->SetAttribute("translate_y", m_localTranslation.y);
|
m_localScale.setXMLAttribute("scale", e);
|
||||||
e->SetAttribute("translate_z", m_localTranslation.z);
|
(m_localRotation * (180.0f / M_PI)).setXMLAttribute("rotate", e);
|
||||||
e->SetAttribute("scale_x", m_localScale.x);
|
|
||||||
e->SetAttribute("scale_y", m_localScale.y);
|
|
||||||
e->SetAttribute("scale_z", m_localScale.z);
|
m_rotationOffset.setXMLAttribute("rotate_offset", e);
|
||||||
e->SetAttribute("rotate_x", m_localRotation.x * 180 / M_PI);
|
m_scalingOffset.setXMLAttribute("scale_offset", e);
|
||||||
e->SetAttribute("rotate_y", m_localRotation.y * 180 / M_PI);
|
m_rotationPivot.setXMLAttribute("rotate_pivot", e);
|
||||||
e->SetAttribute("rotate_z", m_localRotation.z * 180 / M_PI);
|
m_scalingPivot.setXMLAttribute("scale_pivot", e);
|
||||||
|
(m_preRotation * (180.0f / M_PI)).setXMLAttribute("pre_rotate", e);
|
||||||
|
(m_postRotation * (180.0f / M_PI)).setXMLAttribute("post_rotate", e);
|
||||||
|
|
||||||
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
|
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
|
||||||
KRNode *child = (*itr);
|
KRNode *child = (*itr);
|
||||||
child->saveXML(n);
|
child->saveXML(n);
|
||||||
@@ -93,26 +116,35 @@ tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) {
|
|||||||
|
|
||||||
void KRNode::loadXML(tinyxml2::XMLElement *e) {
|
void KRNode::loadXML(tinyxml2::XMLElement *e) {
|
||||||
m_name = e->Attribute("name");
|
m_name = e->Attribute("name");
|
||||||
float x,y,z;
|
m_localTranslation.getXMLAttribute("translate", e, KRVector3::Zero());
|
||||||
e->QueryFloatAttribute("translate_x", &x);
|
m_localScale.getXMLAttribute("scale", e, KRVector3::One());
|
||||||
e->QueryFloatAttribute("translate_y", &y);
|
m_localRotation.getXMLAttribute("rotate", e, KRVector3::Zero());
|
||||||
e->QueryFloatAttribute("translate_z", &z);
|
m_localRotation *= M_PI / 180.0f; // Convert degrees to radians
|
||||||
m_localTranslation = KRVector3(x,y,z);
|
m_preRotation.getXMLAttribute("pre_rotate", e, KRVector3::Zero());
|
||||||
|
m_preRotation *= M_PI / 180.0f; // Convert degrees to radians
|
||||||
|
m_postRotation.getXMLAttribute("post_rotate", e, KRVector3::Zero());
|
||||||
|
m_postRotation *= M_PI / 180.0f; // Convert degrees to radians
|
||||||
|
|
||||||
|
|
||||||
|
m_rotationOffset.getXMLAttribute("rotate_offset", e, KRVector3::Zero());
|
||||||
|
m_scalingOffset.getXMLAttribute("scale_offset", e, KRVector3::Zero());
|
||||||
|
m_rotationPivot.getXMLAttribute("rotate_pivot", e, KRVector3::Zero());
|
||||||
|
m_scalingPivot.getXMLAttribute("scale_pivot", e, KRVector3::Zero());
|
||||||
|
|
||||||
|
|
||||||
m_initialLocalTranslation = m_localTranslation;
|
m_initialLocalTranslation = m_localTranslation;
|
||||||
|
|
||||||
e->QueryFloatAttribute("scale_x", &x);
|
|
||||||
e->QueryFloatAttribute("scale_y", &y);
|
|
||||||
e->QueryFloatAttribute("scale_z", &z);
|
|
||||||
m_localScale = KRVector3(x,y,z);
|
|
||||||
m_initialLocalScale = m_localScale;
|
m_initialLocalScale = m_localScale;
|
||||||
|
|
||||||
e->QueryFloatAttribute("rotate_x", &x);
|
|
||||||
e->QueryFloatAttribute("rotate_y", &y);
|
|
||||||
e->QueryFloatAttribute("rotate_z", &z);
|
|
||||||
m_localRotation = KRVector3(x,y,z) / 180.0 * M_PI; // Convert degrees to radians
|
|
||||||
m_initialLocalRotation = m_localRotation;
|
m_initialLocalRotation = m_localRotation;
|
||||||
|
|
||||||
|
m_initialRotationOffset = m_rotationOffset;
|
||||||
|
m_initialScalingOffset = m_scalingOffset;
|
||||||
|
m_initialRotationPivot = m_rotationPivot;
|
||||||
|
m_initialScalingPivot = m_scalingPivot;
|
||||||
|
m_initialPreRotation = m_preRotation;
|
||||||
|
m_initialPostRotation = m_postRotation;
|
||||||
|
|
||||||
m_bindPoseMatrixValid = false;
|
m_bindPoseMatrixValid = false;
|
||||||
|
m_activePoseMatrixValid = false;
|
||||||
m_inverseBindPoseMatrixValid = false;
|
m_inverseBindPoseMatrixValid = false;
|
||||||
m_modelMatrixValid = false;
|
m_modelMatrixValid = false;
|
||||||
m_inverseModelMatrixValid = false;
|
m_inverseModelMatrixValid = false;
|
||||||
@@ -183,6 +215,113 @@ void KRNode::setLocalRotation(const KRVector3 &v, bool set_original) {
|
|||||||
invalidateModelMatrix();
|
invalidateModelMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void KRNode::setRotationOffset(const KRVector3 &v, bool set_original)
|
||||||
|
{
|
||||||
|
m_rotationOffset = v;
|
||||||
|
if(set_original) {
|
||||||
|
m_initialRotationOffset = v;
|
||||||
|
invalidateBindPoseMatrix();
|
||||||
|
}
|
||||||
|
invalidateModelMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRNode::setScalingOffset(const KRVector3 &v, bool set_original)
|
||||||
|
{
|
||||||
|
m_scalingOffset = v;
|
||||||
|
if(set_original) {
|
||||||
|
m_initialScalingOffset = v;
|
||||||
|
invalidateBindPoseMatrix();
|
||||||
|
}
|
||||||
|
invalidateModelMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRNode::setRotationPivot(const KRVector3 &v, bool set_original)
|
||||||
|
{
|
||||||
|
m_rotationPivot = v;
|
||||||
|
if(set_original) {
|
||||||
|
m_initialRotationPivot = v;
|
||||||
|
invalidateBindPoseMatrix();
|
||||||
|
}
|
||||||
|
invalidateModelMatrix();
|
||||||
|
}
|
||||||
|
void KRNode::setScalingPivot(const KRVector3 &v, bool set_original)
|
||||||
|
{
|
||||||
|
m_scalingPivot = v;
|
||||||
|
if(set_original) {
|
||||||
|
m_initialScalingPivot = v;
|
||||||
|
invalidateBindPoseMatrix();
|
||||||
|
}
|
||||||
|
invalidateModelMatrix();
|
||||||
|
}
|
||||||
|
void KRNode::setPreRotation(const KRVector3 &v, bool set_original)
|
||||||
|
{
|
||||||
|
m_preRotation = v;
|
||||||
|
if(set_original) {
|
||||||
|
m_initialPreRotation = v;
|
||||||
|
invalidateBindPoseMatrix();
|
||||||
|
}
|
||||||
|
invalidateModelMatrix();
|
||||||
|
}
|
||||||
|
void KRNode::setPostRotation(const KRVector3 &v, bool set_original)
|
||||||
|
{
|
||||||
|
m_postRotation = v;
|
||||||
|
if(set_original) {
|
||||||
|
m_initialPostRotation = v;
|
||||||
|
invalidateBindPoseMatrix();
|
||||||
|
}
|
||||||
|
invalidateModelMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
const KRVector3 &KRNode::getRotationOffset()
|
||||||
|
{
|
||||||
|
return m_rotationOffset;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getScalingOffset()
|
||||||
|
{
|
||||||
|
return m_scalingOffset;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getRotationPivot()
|
||||||
|
{
|
||||||
|
return m_rotationPivot;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getScalingPivot()
|
||||||
|
{
|
||||||
|
return m_scalingPivot;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getPreRotation()
|
||||||
|
{
|
||||||
|
return m_preRotation;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getPostRotation()
|
||||||
|
{
|
||||||
|
return m_postRotation;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getInitialRotationOffset()
|
||||||
|
{
|
||||||
|
return m_initialRotationOffset;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getInitialScalingOffset()
|
||||||
|
{
|
||||||
|
return m_initialScalingOffset;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getInitialRotationPivot()
|
||||||
|
{
|
||||||
|
return m_initialRotationPivot;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getInitialScalingPivot()
|
||||||
|
{
|
||||||
|
return m_initialScalingPivot;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getInitialPreRotation()
|
||||||
|
{
|
||||||
|
return m_initialPreRotation;
|
||||||
|
}
|
||||||
|
const KRVector3 &KRNode::getInitialPostRotation()
|
||||||
|
{
|
||||||
|
return m_initialPostRotation;
|
||||||
|
}
|
||||||
|
|
||||||
const KRVector3 &KRNode::getLocalTranslation() {
|
const KRVector3 &KRNode::getLocalTranslation() {
|
||||||
return m_localTranslation;
|
return m_localTranslation;
|
||||||
}
|
}
|
||||||
@@ -211,7 +350,7 @@ const KRVector3 KRNode::getWorldScale() {
|
|||||||
return KRMat4::DotNoTranslate(getModelMatrix(), m_localScale);
|
return KRMat4::DotNoTranslate(getModelMatrix(), m_localScale);
|
||||||
}
|
}
|
||||||
const KRVector3 KRNode::getWorldRotation() {
|
const KRVector3 KRNode::getWorldRotation() {
|
||||||
KRVector3 world_rotation = m_localRotation;
|
KRVector3 world_rotation = (-KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).eulerXYZ();;
|
||||||
if(m_parentNode) {
|
if(m_parentNode) {
|
||||||
KRVector3 parent_rotation = m_parentNode->getWorldRotation();
|
KRVector3 parent_rotation = m_parentNode->getWorldRotation();
|
||||||
world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ();
|
world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ();
|
||||||
@@ -219,6 +358,24 @@ const KRVector3 KRNode::getWorldRotation() {
|
|||||||
return world_rotation;
|
return world_rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const KRVector3 KRNode::getBindPoseWorldRotation() {
|
||||||
|
KRVector3 world_rotation = (-KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).eulerXYZ();
|
||||||
|
if(dynamic_cast<KRBone *>(m_parentNode)) {
|
||||||
|
KRVector3 parent_rotation = m_parentNode->getBindPoseWorldRotation();
|
||||||
|
world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ();
|
||||||
|
}
|
||||||
|
return world_rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KRVector3 KRNode::getActivePoseWorldRotation() {
|
||||||
|
KRVector3 world_rotation = (KRQuaternion(m_preRotation) * KRQuaternion(m_localRotation) * -KRQuaternion(m_postRotation)).eulerXYZ();
|
||||||
|
if(dynamic_cast<KRBone *>(m_parentNode)) {
|
||||||
|
KRVector3 parent_rotation = m_parentNode->getActivePoseWorldRotation();
|
||||||
|
world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ();
|
||||||
|
}
|
||||||
|
return world_rotation;
|
||||||
|
}
|
||||||
|
|
||||||
std::string KRNode::getElementName() {
|
std::string KRNode::getElementName() {
|
||||||
return "node";
|
return "node";
|
||||||
}
|
}
|
||||||
@@ -310,6 +467,7 @@ KRAABB KRNode::getBounds() {
|
|||||||
void KRNode::invalidateModelMatrix()
|
void KRNode::invalidateModelMatrix()
|
||||||
{
|
{
|
||||||
m_modelMatrixValid = false;
|
m_modelMatrixValid = false;
|
||||||
|
m_activePoseMatrixValid = false;
|
||||||
m_inverseModelMatrixValid = false;
|
m_inverseModelMatrixValid = false;
|
||||||
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
|
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
|
||||||
KRNode *child = (*itr);
|
KRNode *child = (*itr);
|
||||||
@@ -336,15 +494,62 @@ const KRMat4 &KRNode::getModelMatrix()
|
|||||||
if(!m_modelMatrixValid) {
|
if(!m_modelMatrixValid) {
|
||||||
m_modelMatrix = KRMat4();
|
m_modelMatrix = KRMat4();
|
||||||
|
|
||||||
|
bool parent_is_bone = false;
|
||||||
|
if(dynamic_cast<KRBone *>(m_parentNode)) {
|
||||||
|
parent_is_bone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getScaleCompensation() && parent_is_bone) {
|
||||||
|
m_modelMatrix.translate(-m_scalingPivot);
|
||||||
m_modelMatrix.scale(m_localScale);
|
m_modelMatrix.scale(m_localScale);
|
||||||
|
m_modelMatrix.translate(m_scalingPivot);
|
||||||
|
m_modelMatrix.translate(m_scalingOffset);
|
||||||
|
m_modelMatrix.translate(-m_rotationPivot);
|
||||||
|
m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS);
|
||||||
|
m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS);
|
||||||
|
m_modelMatrix.rotate(-m_postRotation.x, X_AXIS);
|
||||||
m_modelMatrix.rotate(m_localRotation.x, X_AXIS);
|
m_modelMatrix.rotate(m_localRotation.x, X_AXIS);
|
||||||
m_modelMatrix.rotate(m_localRotation.y, Y_AXIS);
|
m_modelMatrix.rotate(m_localRotation.y, Y_AXIS);
|
||||||
m_modelMatrix.rotate(m_localRotation.z, Z_AXIS);
|
m_modelMatrix.rotate(m_localRotation.z, Z_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_preRotation.x, X_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_preRotation.y, Y_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_preRotation.z, Z_AXIS);
|
||||||
|
m_modelMatrix.translate(m_rotationPivot);
|
||||||
|
m_modelMatrix.translate(m_rotationOffset);
|
||||||
|
//m_modelMatrix.translate(m_localTranslation);
|
||||||
|
if(m_parentNode) {
|
||||||
|
|
||||||
|
m_modelMatrix.rotate(m_parentNode->getWorldRotation());
|
||||||
|
m_modelMatrix.translate(KRMat4::Dot(m_parentNode->getModelMatrix(), m_localTranslation));
|
||||||
|
} else {
|
||||||
m_modelMatrix.translate(m_localTranslation);
|
m_modelMatrix.translate(m_localTranslation);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
|
||||||
|
m_modelMatrix.translate(-m_scalingPivot);
|
||||||
|
m_modelMatrix.scale(m_localScale);
|
||||||
|
m_modelMatrix.translate(m_scalingPivot);
|
||||||
|
m_modelMatrix.translate(m_scalingOffset);
|
||||||
|
m_modelMatrix.translate(-m_rotationPivot);
|
||||||
|
m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS);
|
||||||
|
m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS);
|
||||||
|
m_modelMatrix.rotate(-m_postRotation.x, X_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_localRotation.x, X_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_localRotation.y, Y_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_localRotation.z, Z_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_preRotation.x, X_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_preRotation.y, Y_AXIS);
|
||||||
|
m_modelMatrix.rotate(m_preRotation.z, Z_AXIS);
|
||||||
|
m_modelMatrix.translate(m_rotationPivot);
|
||||||
|
m_modelMatrix.translate(m_rotationOffset);
|
||||||
|
m_modelMatrix.translate(m_localTranslation);
|
||||||
|
|
||||||
|
|
||||||
if(m_parentNode) {
|
if(m_parentNode) {
|
||||||
m_modelMatrix *= m_parentNode->getModelMatrix();
|
m_modelMatrix *= m_parentNode->getModelMatrix();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_modelMatrixValid = true;
|
m_modelMatrixValid = true;
|
||||||
|
|
||||||
@@ -352,6 +557,143 @@ const KRMat4 &KRNode::getModelMatrix()
|
|||||||
return m_modelMatrix;
|
return m_modelMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const KRMat4 &KRNode::getBindPoseMatrix()
|
||||||
|
{
|
||||||
|
if(!m_bindPoseMatrixValid) {
|
||||||
|
m_bindPoseMatrix = KRMat4();
|
||||||
|
|
||||||
|
bool parent_is_bone = false;
|
||||||
|
if(dynamic_cast<KRBone *>(m_parentNode)) {
|
||||||
|
parent_is_bone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getScaleCompensation() && parent_is_bone) {
|
||||||
|
m_bindPoseMatrix.translate(-m_initialScalingPivot);
|
||||||
|
m_bindPoseMatrix.scale(m_initialLocalScale);
|
||||||
|
m_bindPoseMatrix.translate(m_initialScalingPivot);
|
||||||
|
m_bindPoseMatrix.translate(m_initialScalingOffset);
|
||||||
|
m_bindPoseMatrix.translate(-m_initialRotationPivot);
|
||||||
|
m_bindPoseMatrix.rotate(-m_initialPostRotation.z, Z_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(-m_initialPostRotation.y, Y_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(-m_initialPostRotation.x, X_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_initialLocalRotation.z, Z_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_initialPreRotation.x, X_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_initialPreRotation.y, Y_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_initialPreRotation.z, Z_AXIS);
|
||||||
|
m_bindPoseMatrix.translate(m_initialRotationPivot);
|
||||||
|
m_bindPoseMatrix.translate(m_initialRotationOffset);
|
||||||
|
//m_bindPoseMatrix.translate(m_localTranslation);
|
||||||
|
if(m_parentNode) {
|
||||||
|
|
||||||
|
m_bindPoseMatrix.rotate(m_parentNode->getBindPoseWorldRotation());
|
||||||
|
m_bindPoseMatrix.translate(KRMat4::Dot(m_parentNode->getBindPoseMatrix(), m_localTranslation));
|
||||||
|
} else {
|
||||||
|
m_bindPoseMatrix.translate(m_localTranslation);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
|
||||||
|
m_bindPoseMatrix.translate(-m_scalingPivot);
|
||||||
|
m_bindPoseMatrix.scale(m_localScale);
|
||||||
|
m_bindPoseMatrix.translate(m_scalingPivot);
|
||||||
|
m_bindPoseMatrix.translate(m_scalingOffset);
|
||||||
|
m_bindPoseMatrix.translate(-m_rotationPivot);
|
||||||
|
m_bindPoseMatrix.rotate(-m_postRotation.z, Z_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(-m_postRotation.y, Y_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(-m_postRotation.x, X_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_localRotation.x, X_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_localRotation.y, Y_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_localRotation.z, Z_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_preRotation.x, X_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_preRotation.y, Y_AXIS);
|
||||||
|
m_bindPoseMatrix.rotate(m_preRotation.z, Z_AXIS);
|
||||||
|
m_bindPoseMatrix.translate(m_rotationPivot);
|
||||||
|
m_bindPoseMatrix.translate(m_rotationOffset);
|
||||||
|
m_bindPoseMatrix.translate(m_localTranslation);
|
||||||
|
|
||||||
|
|
||||||
|
if(m_parentNode && parent_is_bone) {
|
||||||
|
m_bindPoseMatrix *= m_parentNode->getBindPoseMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bindPoseMatrixValid = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
return m_bindPoseMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KRMat4 &KRNode::getActivePoseMatrix()
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!m_activePoseMatrixValid) {
|
||||||
|
m_activePoseMatrix = KRMat4();
|
||||||
|
|
||||||
|
bool parent_is_bone = false;
|
||||||
|
if(dynamic_cast<KRBone *>(m_parentNode)) {
|
||||||
|
parent_is_bone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getScaleCompensation() && parent_is_bone) {
|
||||||
|
m_activePoseMatrix.translate(-m_scalingPivot);
|
||||||
|
m_activePoseMatrix.scale(m_localScale);
|
||||||
|
m_activePoseMatrix.translate(m_scalingPivot);
|
||||||
|
m_activePoseMatrix.translate(m_scalingOffset);
|
||||||
|
m_activePoseMatrix.translate(-m_rotationPivot);
|
||||||
|
m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_preRotation.x, X_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_preRotation.y, Y_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_preRotation.z, Z_AXIS);
|
||||||
|
m_activePoseMatrix.translate(m_rotationPivot);
|
||||||
|
m_activePoseMatrix.translate(m_rotationOffset);
|
||||||
|
if(m_parentNode) {
|
||||||
|
|
||||||
|
m_activePoseMatrix.rotate(m_parentNode->getWorldRotation());
|
||||||
|
m_activePoseMatrix.translate(KRMat4::Dot(m_parentNode->getActivePoseMatrix(), m_localTranslation));
|
||||||
|
} else {
|
||||||
|
m_activePoseMatrix.translate(m_localTranslation);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1
|
||||||
|
m_activePoseMatrix.translate(-m_scalingPivot);
|
||||||
|
m_activePoseMatrix.scale(m_localScale);
|
||||||
|
m_activePoseMatrix.translate(m_scalingPivot);
|
||||||
|
m_activePoseMatrix.translate(m_scalingOffset);
|
||||||
|
m_activePoseMatrix.translate(-m_rotationPivot);
|
||||||
|
m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_preRotation.x, X_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_preRotation.y, Y_AXIS);
|
||||||
|
m_activePoseMatrix.rotate(m_preRotation.z, Z_AXIS);
|
||||||
|
m_activePoseMatrix.translate(m_rotationPivot);
|
||||||
|
m_activePoseMatrix.translate(m_rotationOffset);
|
||||||
|
m_activePoseMatrix.translate(m_localTranslation);
|
||||||
|
|
||||||
|
|
||||||
|
if(m_parentNode && parent_is_bone) {
|
||||||
|
m_activePoseMatrix *= m_parentNode->getActivePoseMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_activePoseMatrixValid = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
return m_activePoseMatrix;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const KRMat4 &KRNode::getInverseModelMatrix()
|
const KRMat4 &KRNode::getInverseModelMatrix()
|
||||||
{
|
{
|
||||||
if(!m_inverseModelMatrixValid) {
|
if(!m_inverseModelMatrixValid) {
|
||||||
@@ -360,29 +702,6 @@ const KRMat4 &KRNode::getInverseModelMatrix()
|
|||||||
return m_inverseModelMatrix;
|
return m_inverseModelMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
const KRMat4 &KRNode::getBindPoseMatrix()
|
|
||||||
{
|
|
||||||
if(!m_bindPoseMatrixValid) {
|
|
||||||
m_bindPoseMatrix = KRMat4();
|
|
||||||
|
|
||||||
|
|
||||||
m_bindPoseMatrix.scale(m_initialLocalScale);
|
|
||||||
m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS);
|
|
||||||
m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS);
|
|
||||||
m_bindPoseMatrix.rotate(m_initialLocalRotation.z, Z_AXIS);
|
|
||||||
m_bindPoseMatrix.translate(m_initialLocalTranslation);
|
|
||||||
|
|
||||||
KRBone *parentBone = dynamic_cast<KRBone *>(m_parentNode);
|
|
||||||
if(parentBone) {
|
|
||||||
|
|
||||||
m_bindPoseMatrix *= parentBone->getBindPoseMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bindPoseMatrixValid = true;
|
|
||||||
}
|
|
||||||
return m_bindPoseMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
const KRMat4 &KRNode::getInverseBindPoseMatrix()
|
const KRMat4 &KRNode::getInverseBindPoseMatrix()
|
||||||
{
|
{
|
||||||
if(!m_inverseBindPoseMatrixValid ) {
|
if(!m_inverseBindPoseMatrixValid ) {
|
||||||
|
|||||||
@@ -62,6 +62,29 @@ public:
|
|||||||
void setLocalScale(const KRVector3 &v, bool set_original = false);
|
void setLocalScale(const KRVector3 &v, bool set_original = false);
|
||||||
void setLocalRotation(const KRVector3 &v, bool set_original = false);
|
void setLocalRotation(const KRVector3 &v, bool set_original = false);
|
||||||
|
|
||||||
|
|
||||||
|
void setRotationOffset(const KRVector3 &v, bool set_original = false);
|
||||||
|
void setScalingOffset(const KRVector3 &v, bool set_original = false);
|
||||||
|
void setRotationPivot(const KRVector3 &v, bool set_original = false);
|
||||||
|
void setScalingPivot(const KRVector3 &v, bool set_original = false);
|
||||||
|
void setPreRotation(const KRVector3 &v, bool set_original = false);
|
||||||
|
void setPostRotation(const KRVector3 &v, bool set_original = false);
|
||||||
|
|
||||||
|
const KRVector3 &getRotationOffset();
|
||||||
|
const KRVector3 &getScalingOffset();
|
||||||
|
const KRVector3 &getRotationPivot();
|
||||||
|
const KRVector3 &getScalingPivot();
|
||||||
|
const KRVector3 &getPreRotation();
|
||||||
|
const KRVector3 &getPostRotation();
|
||||||
|
|
||||||
|
const KRVector3 &getInitialRotationOffset();
|
||||||
|
const KRVector3 &getInitialScalingOffset();
|
||||||
|
const KRVector3 &getInitialRotationPivot();
|
||||||
|
const KRVector3 &getInitialScalingPivot();
|
||||||
|
const KRVector3 &getInitialPreRotation();
|
||||||
|
const KRVector3 &getInitialPostRotation();
|
||||||
|
|
||||||
|
|
||||||
const KRVector3 &getLocalTranslation();
|
const KRVector3 &getLocalTranslation();
|
||||||
const KRVector3 &getLocalScale();
|
const KRVector3 &getLocalScale();
|
||||||
const KRVector3 &getLocalRotation();
|
const KRVector3 &getLocalRotation();
|
||||||
@@ -74,6 +97,9 @@ public:
|
|||||||
const KRVector3 getWorldScale();
|
const KRVector3 getWorldScale();
|
||||||
const KRVector3 getWorldRotation();
|
const KRVector3 getWorldRotation();
|
||||||
|
|
||||||
|
const KRVector3 getBindPoseWorldRotation();
|
||||||
|
const KRVector3 getActivePoseWorldRotation();
|
||||||
|
|
||||||
const KRVector3 localToWorld(const KRVector3 &local_point);
|
const KRVector3 localToWorld(const KRVector3 &local_point);
|
||||||
const KRVector3 worldToLocal(const KRVector3 &world_point);
|
const KRVector3 worldToLocal(const KRVector3 &world_point);
|
||||||
|
|
||||||
@@ -85,6 +111,7 @@ public:
|
|||||||
const KRMat4 &getModelMatrix();
|
const KRMat4 &getModelMatrix();
|
||||||
const KRMat4 &getInverseModelMatrix();
|
const KRMat4 &getInverseModelMatrix();
|
||||||
const KRMat4 &getBindPoseMatrix();
|
const KRMat4 &getBindPoseMatrix();
|
||||||
|
const KRMat4 &getActivePoseMatrix();
|
||||||
const KRMat4 &getInverseBindPoseMatrix();
|
const KRMat4 &getInverseBindPoseMatrix();
|
||||||
|
|
||||||
enum node_attribute_type {
|
enum node_attribute_type {
|
||||||
@@ -112,16 +139,31 @@ public:
|
|||||||
virtual void updateLODVisibility(const KRViewport &viewport);
|
virtual void updateLODVisibility(const KRViewport &viewport);
|
||||||
bool lodIsVisible();
|
bool lodIsVisible();
|
||||||
|
|
||||||
|
void setScaleCompensation(bool scale_compensation);
|
||||||
|
bool getScaleCompensation();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
KRVector3 m_localTranslation;
|
KRVector3 m_localTranslation;
|
||||||
KRVector3 m_localScale;
|
KRVector3 m_localScale;
|
||||||
KRVector3 m_localRotation;
|
KRVector3 m_localRotation;
|
||||||
|
|
||||||
|
KRVector3 m_rotationOffset;
|
||||||
|
KRVector3 m_scalingOffset;
|
||||||
|
KRVector3 m_rotationPivot;
|
||||||
|
KRVector3 m_scalingPivot;
|
||||||
|
KRVector3 m_preRotation;
|
||||||
|
KRVector3 m_postRotation;
|
||||||
|
|
||||||
KRVector3 m_initialLocalTranslation;
|
KRVector3 m_initialLocalTranslation;
|
||||||
KRVector3 m_initialLocalScale;
|
KRVector3 m_initialLocalScale;
|
||||||
KRVector3 m_initialLocalRotation;
|
KRVector3 m_initialLocalRotation;
|
||||||
|
|
||||||
|
KRVector3 m_initialRotationOffset;
|
||||||
|
KRVector3 m_initialScalingOffset;
|
||||||
|
KRVector3 m_initialRotationPivot;
|
||||||
|
KRVector3 m_initialScalingPivot;
|
||||||
|
KRVector3 m_initialPreRotation;
|
||||||
|
KRVector3 m_initialPostRotation;
|
||||||
|
|
||||||
bool m_lod_visible;
|
bool m_lod_visible;
|
||||||
void hideLOD();
|
void hideLOD();
|
||||||
@@ -138,10 +180,12 @@ private:
|
|||||||
KRMat4 m_modelMatrix;
|
KRMat4 m_modelMatrix;
|
||||||
KRMat4 m_inverseModelMatrix;
|
KRMat4 m_inverseModelMatrix;
|
||||||
KRMat4 m_bindPoseMatrix;
|
KRMat4 m_bindPoseMatrix;
|
||||||
|
KRMat4 m_activePoseMatrix;
|
||||||
KRMat4 m_inverseBindPoseMatrix;
|
KRMat4 m_inverseBindPoseMatrix;
|
||||||
bool m_modelMatrixValid;
|
bool m_modelMatrixValid;
|
||||||
bool m_inverseModelMatrixValid;
|
bool m_inverseModelMatrixValid;
|
||||||
bool m_bindPoseMatrixValid;
|
bool m_bindPoseMatrixValid;
|
||||||
|
bool m_activePoseMatrixValid;
|
||||||
bool m_inverseBindPoseMatrixValid;
|
bool m_inverseBindPoseMatrixValid;
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
@@ -151,6 +195,7 @@ private:
|
|||||||
KRScene *m_pScene;
|
KRScene *m_pScene;
|
||||||
|
|
||||||
std::set<KROctreeNode *> m_octree_nodes;
|
std::set<KROctreeNode *> m_octree_nodes;
|
||||||
|
bool m_scale_compensation;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRPointLig
|
|||||||
if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) {
|
if(getContext().getShaderManager()->selectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) {
|
||||||
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f);
|
pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f);
|
||||||
|
|
||||||
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, true, false, false, true, false, false, false, false);
|
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false);
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
|
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRPointLig
|
|||||||
// 1.0f
|
// 1.0f
|
||||||
// ));
|
// ));
|
||||||
//
|
//
|
||||||
// m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, true, false, false, true, false, false);
|
// m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false);
|
||||||
// GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
|
// GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
|
||||||
// }
|
// }
|
||||||
//// }
|
//// }
|
||||||
|
|||||||
@@ -96,13 +96,13 @@ void KRPointLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_
|
|||||||
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
GLDEBUG(glDisable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
// Render a full screen quad
|
// Render a full screen quad
|
||||||
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true);
|
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true);
|
||||||
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||||
} else {
|
} else {
|
||||||
#if GL_OES_vertex_array_object
|
#if GL_OES_vertex_array_object
|
||||||
GLDEBUG(glBindVertexArrayOES(0));
|
GLDEBUG(glBindVertexArrayOES(0));
|
||||||
#endif
|
#endif
|
||||||
m_pContext->getModelManager()->configureAttribs(true, false, false, false, false, false, false);
|
m_pContext->getModelManager()->configureAttribs(1 << KRMesh::KRENGINE_ATTRIB_VERTEX);
|
||||||
// Render sphere of light's influence
|
// Render sphere of light's influence
|
||||||
generateMesh();
|
generateMesh();
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ public:
|
|||||||
KRENGINE_DEBUG_DISPLAY_DRAW_CALLS,
|
KRENGINE_DEBUG_DISPLAY_DRAW_CALLS,
|
||||||
KRENGINE_DEBUG_DISPLAY_OCTREE,
|
KRENGINE_DEBUG_DISPLAY_OCTREE,
|
||||||
KRENGINE_DEBUG_DISPLAY_COLLIDERS,
|
KRENGINE_DEBUG_DISPLAY_COLLIDERS,
|
||||||
|
KRENGINE_DEBUG_DISPLAY_BONES,
|
||||||
KRENGINE_DEBUG_DISPLAY_NUMBER
|
KRENGINE_DEBUG_DISPLAY_NUMBER
|
||||||
} debug_display;
|
} debug_display;
|
||||||
|
|
||||||
|
|||||||
@@ -85,13 +85,16 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path)
|
|||||||
// Load the scene.
|
// Load the scene.
|
||||||
lResult = LoadScene(lSdkManager, pFbxScene, path.c_str());
|
lResult = LoadScene(lSdkManager, pFbxScene, path.c_str());
|
||||||
|
|
||||||
// ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====----
|
|
||||||
|
|
||||||
printf("Baking pivots...\n");
|
|
||||||
KFbxNode* pNode = pFbxScene->GetRootNode();
|
KFbxNode* pNode = pFbxScene->GetRootNode();
|
||||||
|
|
||||||
|
// ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====----
|
||||||
|
/*
|
||||||
|
printf("Baking pivots...\n");
|
||||||
|
|
||||||
if(pNode) {
|
if(pNode) {
|
||||||
pNode->ResetPivotSetAndConvertAnimation();
|
pNode->ResetPivotSetAndConvertAnimation();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// ----====---- Import Animation Layers ----====----
|
// ----====---- Import Animation Layers ----====----
|
||||||
printf("\nLoading animations...\n");
|
printf("\nLoading animations...\n");
|
||||||
@@ -660,12 +663,6 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
|
|||||||
KFbxVector4 lZero(0.0, 0.0, 0.0);
|
KFbxVector4 lZero(0.0, 0.0, 0.0);
|
||||||
KFbxVector4 lOne(1.0, 1.0, 1.0);
|
KFbxVector4 lOne(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
assert(post_rotation == lZero);
|
|
||||||
assert(pre_rotation == lZero);
|
|
||||||
assert(rotation_offset == lZero);
|
|
||||||
assert(scaling_offset == lZero);
|
|
||||||
assert(rotation_pivot == lZero);
|
|
||||||
assert(scaling_pivot == lZero);
|
|
||||||
assert(geometric_rotation == lZero);
|
assert(geometric_rotation == lZero);
|
||||||
assert(geometric_translation == lZero);
|
assert(geometric_translation == lZero);
|
||||||
assert(geometric_scaling == lOne);
|
assert(geometric_scaling == lOne);
|
||||||
@@ -675,6 +672,13 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
|
|||||||
KRVector3 node_rotation = KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI;
|
KRVector3 node_rotation = KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI;
|
||||||
KRVector3 node_scale = KRVector3(local_scale[0], local_scale[1], local_scale[2]);
|
KRVector3 node_scale = KRVector3(local_scale[0], local_scale[1], local_scale[2]);
|
||||||
|
|
||||||
|
KRVector3 node_rotation_offset = KRVector3(rotation_offset[0], rotation_offset[1], rotation_offset[2]);
|
||||||
|
KRVector3 node_scaling_offset = KRVector3(scaling_offset[0], scaling_offset[1], scaling_offset[2]);
|
||||||
|
KRVector3 node_rotation_pivot = KRVector3(rotation_pivot[0], rotation_pivot[1], rotation_pivot[2]);
|
||||||
|
KRVector3 node_scaling_pivot = KRVector3(scaling_pivot[0], scaling_pivot[1], scaling_pivot[2]);
|
||||||
|
KRVector3 node_pre_rotation = KRVector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI;
|
||||||
|
KRVector3 node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI;
|
||||||
|
|
||||||
// printf(" Local Translation: %f %f %f\n", local_translation[0], local_translation[1], local_translation[2]);
|
// printf(" Local Translation: %f %f %f\n", local_translation[0], local_translation[1], local_translation[2]);
|
||||||
// printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]);
|
// printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]);
|
||||||
// printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]);
|
// printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]);
|
||||||
@@ -740,6 +744,15 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
|
|||||||
new_node->setLocalRotation(node_rotation);
|
new_node->setLocalRotation(node_rotation);
|
||||||
new_node->setLocalTranslation(node_translation);
|
new_node->setLocalTranslation(node_translation);
|
||||||
new_node->setLocalScale(node_scale);
|
new_node->setLocalScale(node_scale);
|
||||||
|
|
||||||
|
|
||||||
|
new_node->setRotationOffset(node_rotation_offset);
|
||||||
|
new_node->setScalingOffset(node_scaling_offset);
|
||||||
|
new_node->setRotationPivot(node_rotation_pivot);
|
||||||
|
new_node->setScalingPivot(node_scaling_pivot);
|
||||||
|
new_node->setPreRotation(node_pre_rotation);
|
||||||
|
new_node->setPostRotation(node_post_rotation);
|
||||||
|
|
||||||
new_node->setUseWorldUnits(use_world_space_units);
|
new_node->setUseWorldUnits(use_world_space_units);
|
||||||
parent_node->addChild(new_node);
|
parent_node->addChild(new_node);
|
||||||
|
|
||||||
@@ -822,6 +835,12 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
|
|||||||
new_node->setLocalRotation(node_rotation);
|
new_node->setLocalRotation(node_rotation);
|
||||||
new_node->setLocalTranslation(node_translation);
|
new_node->setLocalTranslation(node_translation);
|
||||||
new_node->setLocalScale(node_scale);
|
new_node->setLocalScale(node_scale);
|
||||||
|
new_node->setRotationOffset(node_rotation_offset);
|
||||||
|
new_node->setScalingOffset(node_scaling_offset);
|
||||||
|
new_node->setRotationPivot(node_rotation_pivot);
|
||||||
|
new_node->setScalingPivot(node_scaling_pivot);
|
||||||
|
new_node->setPreRotation(node_pre_rotation);
|
||||||
|
new_node->setPostRotation(node_post_rotation);
|
||||||
parent_node->addChild(new_node);
|
parent_node->addChild(new_node);
|
||||||
|
|
||||||
// Load child nodes
|
// Load child nodes
|
||||||
@@ -1056,7 +1075,7 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx
|
|||||||
}
|
}
|
||||||
weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = bone_weight;
|
weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = bone_weight;
|
||||||
weight_info.bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = target_bone_index;
|
weight_info.bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = target_bone_index;
|
||||||
for(int bone_index=KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1; bone_index >=0; bone_index--) {
|
for(int bone_index=KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 2; bone_index >=0; bone_index--) {
|
||||||
if(bone_weight > weight_info.weights[bone_index]) {
|
if(bone_weight > weight_info.weights[bone_index]) {
|
||||||
weight_info.weights[bone_index+1] = weight_info.weights[bone_index];
|
weight_info.weights[bone_index+1] = weight_info.weights[bone_index];
|
||||||
weight_info.bone_indexes[bone_index+1] = weight_info.bone_indexes[bone_index];
|
weight_info.bone_indexes[bone_index+1] = weight_info.bone_indexes[bone_index];
|
||||||
|
|||||||
@@ -182,18 +182,6 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map<KRAABB, int> &visi
|
|||||||
if(bOcclusionResultsPass) {
|
if(bOcclusionResultsPass) {
|
||||||
// ----====---- Occlusion results pass ----====----
|
// ----====---- Occlusion results pass ----====----
|
||||||
if(pOctreeNode->m_occlusionTested) {
|
if(pOctreeNode->m_occlusionTested) {
|
||||||
/*
|
|
||||||
GLuint hasBeenTested = 0;
|
|
||||||
int c =0;
|
|
||||||
while(!hasBeenTested) {
|
|
||||||
GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_AVAILABLE_EXT, &hasBeenTested)); // FINDME, HACK!! This needs to be replaced with asynchonous logic
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
if(c > 1) {
|
|
||||||
fprintf(stderr, "GL_QUERY_RESULT_AVAILABLE_EXT count = %i\n", c);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLuint params = 0;
|
GLuint params = 0;
|
||||||
GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms));
|
GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms));
|
||||||
|
|
||||||
@@ -283,7 +271,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map<KRAABB, int> &visi
|
|||||||
KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix();
|
KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix();
|
||||||
|
|
||||||
|
|
||||||
getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, true, false, false, false, false, false, false, true);
|
getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true);
|
||||||
|
|
||||||
// Enable additive blending
|
// Enable additive blending
|
||||||
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#ifndef KRSTOCKGEOMETRY_H
|
#ifndef KRSTOCKGEOMETRY_H
|
||||||
#define KRSTOCKGEOMETRY_H
|
#define KRSTOCKGEOMETRY_H
|
||||||
|
|
||||||
|
#include "KRMesh.h"
|
||||||
|
|
||||||
static const GLfloat KRENGINE_VBO_3D_CUBE[] = {
|
static const GLfloat KRENGINE_VBO_3D_CUBE[] = {
|
||||||
1.0, 1.0, 1.0,
|
1.0, 1.0, 1.0,
|
||||||
-1.0, 1.0, 1.0,
|
-1.0, 1.0, 1.0,
|
||||||
@@ -27,6 +29,7 @@ static const GLfloat KRENGINE_VBO_3D_CUBE[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int KRENGINE_VBO_3D_CUBE_SIZE = sizeof(GLfloat) * 3 * 14;
|
static int KRENGINE_VBO_3D_CUBE_SIZE = sizeof(GLfloat) * 3 * 14;
|
||||||
|
static const __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX);
|
||||||
|
|
||||||
static const GLfloat KRENGINE_VERTICES_2D_SQUARE[] = {
|
static const GLfloat KRENGINE_VERTICES_2D_SQUARE[] = {
|
||||||
-1.0f, -1.0f,
|
-1.0f, -1.0f,
|
||||||
@@ -50,6 +53,7 @@ static const GLfloat KRENGINE_VBO_2D_SQUARE[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const int KRENGINE_VBO_2D_SQUARE_SIZE = sizeof(GLfloat) * 5 * 4;
|
static const int KRENGINE_VBO_2D_SQUARE_SIZE = sizeof(GLfloat) * 5 * 4;
|
||||||
|
static const __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ KRTexture *KRTextureManager::getTextureCube(const char *szName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KRTexture *KRTextureManager::getTexture(const std::string &name) {
|
KRTexture *KRTextureManager::getTexture(const std::string &name) {
|
||||||
|
|
||||||
std::string lowerName = name;
|
std::string lowerName = name;
|
||||||
std::transform(lowerName.begin(), lowerName.end(),
|
std::transform(lowerName.begin(), lowerName.end(),
|
||||||
lowerName.begin(), ::tolower);
|
lowerName.begin(), ::tolower);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "KREngine-common.h"
|
#include "KREngine-common.h"
|
||||||
#include "KRVector3.h"
|
#include "KRVector3.h"
|
||||||
|
#include "tinyxml2.h"
|
||||||
|
|
||||||
//default constructor
|
//default constructor
|
||||||
KRVector3::KRVector3()
|
KRVector3::KRVector3()
|
||||||
@@ -315,3 +316,26 @@ void KRVector3::setUniform(GLint location) const
|
|||||||
{
|
{
|
||||||
if(location != -1) GLDEBUG(glUniform3f(location, x, y, z));
|
if(location != -1) GLDEBUG(glUniform3f(location, x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KRVector3::setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e)
|
||||||
|
{
|
||||||
|
// TODO - Increase number of digits after the decimal in floating point format (6 -> 12?)
|
||||||
|
// FINDME, TODO - This needs optimization...
|
||||||
|
e->SetAttribute((base_name + "_x").c_str(), x);
|
||||||
|
e->SetAttribute((base_name + "_y").c_str(), y);
|
||||||
|
e->SetAttribute((base_name + "_z").c_str(), z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRVector3::getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value)
|
||||||
|
{
|
||||||
|
float new_x,new_y,new_z;
|
||||||
|
if(e->QueryFloatAttribute((base_name + "_x").c_str(), &new_x) == tinyxml2::XML_SUCCESS
|
||||||
|
&& e->QueryFloatAttribute((base_name + "_y").c_str(), &new_y) == tinyxml2::XML_SUCCESS
|
||||||
|
&& e->QueryFloatAttribute((base_name + "_z").c_str(), &new_z) == tinyxml2::XML_SUCCESS) {
|
||||||
|
x = new_x;
|
||||||
|
y = new_y;
|
||||||
|
z = new_z;
|
||||||
|
} else {
|
||||||
|
*this = default_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "KREngine-common.h"
|
#include "KREngine-common.h"
|
||||||
|
|
||||||
|
|
||||||
class KRVector4;
|
class KRVector4;
|
||||||
|
|
||||||
class KRVector3 {
|
class KRVector3 {
|
||||||
@@ -103,6 +104,9 @@ public:
|
|||||||
static void OrthoNormalize(KRVector3 &normal, KRVector3 &tangent); // Gram-Schmidt Orthonormalization
|
static void OrthoNormalize(KRVector3 &normal, KRVector3 &tangent); // Gram-Schmidt Orthonormalization
|
||||||
|
|
||||||
void setUniform(GLint location) const;
|
void setUniform(GLint location) const;
|
||||||
|
|
||||||
|
void setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e);
|
||||||
|
void getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|||||||
@@ -393,4 +393,8 @@ void main()
|
|||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BONE_COUNT > 0
|
||||||
|
gl_FragColor.b = 1.0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,13 +29,16 @@
|
|||||||
// or implied, of Kearwood Gilbert.
|
// or implied, of Kearwood Gilbert.
|
||||||
//
|
//
|
||||||
|
|
||||||
attribute highp vec3 vertex_position, vertex_normal, vertex_tangent;
|
attribute highp vec3 vertex_position, vertex_normal;
|
||||||
|
#if HAS_NORMAL_MAP == 1
|
||||||
|
attribute highp vec3 vertex_tangent;
|
||||||
|
#endif
|
||||||
attribute mediump vec2 vertex_uv;
|
attribute mediump vec2 vertex_uv;
|
||||||
uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices
|
uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices
|
||||||
|
|
||||||
#if BONE_COUNT > 0
|
#if BONE_COUNT > 0
|
||||||
attribute highp vec4 bone_weights;
|
attribute highp vec4 bone_weights;
|
||||||
attribute mediump vec4 bone_indexes;
|
attribute highp vec4 bone_indexes;
|
||||||
uniform highp mat4 bone_transforms[BONE_COUNT];
|
uniform highp mat4 bone_transforms[BONE_COUNT];
|
||||||
#else
|
#else
|
||||||
#define vertex_position_skinned vertex_position
|
#define vertex_position_skinned vertex_position
|
||||||
@@ -169,30 +172,28 @@ void main()
|
|||||||
mediump vec4 scaled_bone_weights = bone_weights;
|
mediump vec4 scaled_bone_weights = bone_weights;
|
||||||
|
|
||||||
//scaled_bone_indexes = vec4(1.0, 0.0, 0.0, 0.0);
|
//scaled_bone_indexes = vec4(1.0, 0.0, 0.0, 0.0);
|
||||||
// scaled_bone_weights = vec4(1.0, 0.0, 0.0, 0.0);
|
scaled_bone_weights = vec4(1.0, 0.0, 0.0, 0.0);
|
||||||
highp vec3 vertex_position_skinned =
|
|
||||||
((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_position, 1.0)).xyz * scaled_bone_weights.x) +
|
|
||||||
((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_position, 1.0)).xyz * scaled_bone_weights.y) +
|
|
||||||
((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_position, 1.0)).xyz * scaled_bone_weights.z) +
|
|
||||||
((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_position, 1.0)).xyz * scaled_bone_weights.w);
|
|
||||||
|
|
||||||
highp vec3 vertex_normal_skinned = normalize(
|
highp mat4 skin_matrix =
|
||||||
((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_normal, 1.0)).xyz * scaled_bone_weights.x) +
|
bone_transforms[ int(scaled_bone_indexes.x) ] * scaled_bone_weights.x +
|
||||||
((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_normal, 1.0)).xyz * scaled_bone_weights.y) +
|
bone_transforms[ int(scaled_bone_indexes.y) ] * scaled_bone_weights.y +
|
||||||
((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_normal, 1.0)).xyz * scaled_bone_weights.z) +
|
bone_transforms[ int(scaled_bone_indexes.z) ] * scaled_bone_weights.z +
|
||||||
((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_normal, 1.0)).xyz * scaled_bone_weights.w));
|
bone_transforms[ int(scaled_bone_indexes.w) ] * scaled_bone_weights.w;
|
||||||
|
//skin_matrix = bone_transforms[0];
|
||||||
|
highp vec3 vertex_position_skinned = (skin_matrix * vec4(vertex_position, 1)).xyz;
|
||||||
|
|
||||||
highp vec3 vertex_tangent_skinned = normalize(
|
highp vec3 vertex_normal_skinned = normalize(mat3(skin_matrix) * vertex_normal);
|
||||||
((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_tangent, 1.0)).xyz * scaled_bone_weights.x) +
|
#if HAS_NORMAL_MAP == 1
|
||||||
((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_tangent, 1.0)).xyz * scaled_bone_weights.y) +
|
highp vec3 vertex_tangent_skinned = normalize(mat3(skin_matrix) * vertex_tangent);
|
||||||
((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_tangent, 1.0)).xyz * scaled_bone_weights.z) +
|
|
||||||
((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_tangent, 1.0)).xyz * scaled_bone_weights.w));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Transform position
|
// Transform position
|
||||||
gl_Position = mvp_matrix * vec4(vertex_position_skinned,1.0);
|
gl_Position = mvp_matrix * vec4(vertex_position_skinned,1.0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if HAS_DIFFUSE_MAP == 1 || (HAS_NORMAL_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_SPEC_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_REFLECTION_MAP == 1 && ENABLE_PER_PIXEL == 1)
|
#if HAS_DIFFUSE_MAP == 1 || (HAS_NORMAL_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_SPEC_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_REFLECTION_MAP == 1 && ENABLE_PER_PIXEL == 1)
|
||||||
// Pass UV co-ordinates
|
// Pass UV co-ordinates
|
||||||
texCoord = vertex_uv.st;
|
texCoord = vertex_uv.st;
|
||||||
|
|||||||
Reference in New Issue
Block a user