Accessor.min and Accessor.max are now optional parameter.

Set BufferView.byteStride default value to 0(= tightly packed). Fixes #13.
This commit is contained in:
Syoyo Fujita 2017-07-12 18:29:29 +09:00
parent 965071b309
commit d9d012a5df
3 changed files with 57 additions and 24 deletions

View File

@ -529,15 +529,15 @@ static void DrawMesh(tinygltf::Model &model, const tinygltf::Mesh &mesh) {
const tinygltf::Accessor &accessor = model.accessors[it->second]; const tinygltf::Accessor &accessor = model.accessors[it->second];
glBindBuffer(GL_ARRAY_BUFFER, gBufferState[accessor.bufferView].vb); glBindBuffer(GL_ARRAY_BUFFER, gBufferState[accessor.bufferView].vb);
CheckErrors("bind buffer"); CheckErrors("bind buffer");
int count = 1; int size = 1;
if (accessor.type == TINYGLTF_TYPE_SCALAR) { if (accessor.type == TINYGLTF_TYPE_SCALAR) {
count = 1; size = 1;
} else if (accessor.type == TINYGLTF_TYPE_VEC2) { } else if (accessor.type == TINYGLTF_TYPE_VEC2) {
count = 2; size = 2;
} else if (accessor.type == TINYGLTF_TYPE_VEC3) { } else if (accessor.type == TINYGLTF_TYPE_VEC3) {
count = 3; size = 3;
} else if (accessor.type == TINYGLTF_TYPE_VEC4) { } else if (accessor.type == TINYGLTF_TYPE_VEC4) {
count = 4; size = 4;
} else { } else {
assert(0); assert(0);
} }
@ -546,9 +546,9 @@ static void DrawMesh(tinygltf::Model &model, const tinygltf::Mesh &mesh) {
(it->first.compare("NORMAL") == 0) || (it->first.compare("NORMAL") == 0) ||
(it->first.compare("TEXCOORD_0") == 0)) { (it->first.compare("TEXCOORD_0") == 0)) {
if (gGLProgramState.attribs[it->first] >= 0) { if (gGLProgramState.attribs[it->first] >= 0) {
glVertexAttribPointer(gGLProgramState.attribs[it->first], count, glVertexAttribPointer(gGLProgramState.attribs[it->first], size,
accessor.componentType, GL_FALSE, accessor.componentType, accessor.normalized ? GL_TRUE : GL_FALSE,
0, model.bufferViews[accessor.bufferView].byteStride,
BUFFER_OFFSET(accessor.byteOffset)); BUFFER_OFFSET(accessor.byteOffset));
CheckErrors("vertex attrib pointer"); CheckErrors("vertex attrib pointer");
glEnableVertexAttribArray(gGLProgramState.attribs[it->first]); glEnableVertexAttribArray(gGLProgramState.attribs[it->first]);

View File

@ -409,6 +409,8 @@ static void Dump(const tinygltf::Model &model) {
<< std::endl; << std::endl;
std::cout << Indent(2) << "byteOffset : " << bufferView.byteOffset std::cout << Indent(2) << "byteOffset : " << bufferView.byteOffset
<< std::endl; << std::endl;
std::cout << Indent(2) << "byteStride : " << bufferView.byteStride
<< std::endl;
std::cout << Indent(2) std::cout << Indent(2)
<< "target : " << PrintTarget(bufferView.target) << "target : " << PrintTarget(bufferView.target)
<< std::endl; << std::endl;

View File

@ -386,12 +386,13 @@ struct BufferView {
int buffer; // Required int buffer; // Required
size_t byteOffset; // minimum 0, default 0 size_t byteOffset; // minimum 0, default 0
size_t byteLength; // required, minimum 1 size_t byteLength; // required, minimum 1
size_t byteStride; // minimum 4, maximum 252 (multiple of 4) size_t byteStride; // minimum 4, maximum 252 (multiple of 4), default 0 =
// understood to be tightly packed
int target; // ["ARRAY_BUFFER", "ELEMENT_ARRAY_BUFFER"] int target; // ["ARRAY_BUFFER", "ELEMENT_ARRAY_BUFFER"]
int pad0; int pad0;
Value extras; Value extras;
BufferView() : byteOffset(0), byteStride(4) {} BufferView() : byteOffset(0), byteStride(0) {}
}; };
struct Accessor { struct Accessor {
@ -399,13 +400,16 @@ struct Accessor {
// are not supported // are not supported
std::string name; std::string name;
size_t byteOffset; size_t byteOffset;
bool normalized; // optinal.
int componentType; // (required) One of TINYGLTF_COMPONENT_TYPE_*** int componentType; // (required) One of TINYGLTF_COMPONENT_TYPE_***
size_t count; // required size_t count; // required
int type; // (required) One of TINYGLTF_TYPE_*** .. int type; // (required) One of TINYGLTF_TYPE_*** ..
Value extras; Value extras;
std::vector<double> minValues; // required std::vector<double> minValues; // optional
std::vector<double> maxValues; // required std::vector<double> maxValues; // optional
// TODO(syoyo): "sparse"
Accessor() { bufferView = -1; } Accessor() { bufferView = -1; }
}; };
@ -1122,12 +1126,18 @@ static bool ParseExtrasProperty(Value *ret, const picojson::object &o) {
static bool ParseBooleanProperty(bool *ret, std::string *err, static bool ParseBooleanProperty(bool *ret, std::string *err,
const picojson::object &o, const picojson::object &o,
const std::string &property, bool required) { const std::string &property,
const bool required,
const std::string &parent_node = "") {
picojson::object::const_iterator it = o.find(property); picojson::object::const_iterator it = o.find(property);
if (it == o.end()) { if (it == o.end()) {
if (required) { if (required) {
if (err) { if (err) {
(*err) += "'" + property + "' property is missing.\n"; (*err) += "'" + property + "' property is missing";
if (!parent_node.empty()) {
(*err) += " in " + parent_node;
}
(*err) += ".\n";
} }
} }
return false; return false;
@ -1579,8 +1589,30 @@ static bool ParseBufferView(BufferView *bufferView, std::string *err,
return false; return false;
} }
double byteStride = 4.0; size_t byteStride = 0;
ParseNumberProperty(&byteStride, err, o, "byteStride", false); double byteStrideValue = 0.0;
if (!ParseNumberProperty(&byteStrideValue, err, o, "byteStride", false)) {
// Spec says: When byteStride of referenced bufferView is not defined, it
// means that accessor elements are tightly packed, i.e., effective stride
// equals the size of the element.
// We cannot determine the actual byteStride until Accessor are parsed, thus
// set 0(= tightly packed) here(as done in OpenGL's VertexAttribPoiner)
byteStride = 0;
} else {
byteStride = static_cast<size_t>(byteStrideValue);
}
if ((byteStride > 252) || ((byteStride % 4) != 0)) {
if (err) {
std::stringstream ss;
ss << "Invalid `byteStride' value. `byteStride' must be the multiple of "
"4 : "
<< byteStride << std::endl;
(*err) += ss.str();
}
return false;
}
double target = 0.0; double target = 0.0;
ParseNumberProperty(&target, err, o, "target", false); ParseNumberProperty(&target, err, o, "target", false);
@ -1614,6 +1646,9 @@ static bool ParseAccessor(Accessor *accessor, std::string *err,
double byteOffset = 0.0; double byteOffset = 0.0;
ParseNumberProperty(&byteOffset, err, o, "byteOffset", false, "Accessor"); ParseNumberProperty(&byteOffset, err, o, "byteOffset", false, "Accessor");
bool normalized = false;
ParseBooleanProperty(&normalized, err, o, "normalized", false, "Accessor");
double componentType = 0.0; double componentType = 0.0;
if (!ParseNumberProperty(&componentType, err, o, "componentType", true, if (!ParseNumberProperty(&componentType, err, o, "componentType", true,
"Accessor")) { "Accessor")) {
@ -1657,15 +1692,11 @@ static bool ParseAccessor(Accessor *accessor, std::string *err,
accessor->minValues.clear(); accessor->minValues.clear();
accessor->maxValues.clear(); accessor->maxValues.clear();
if (!ParseNumberArrayProperty(&accessor->minValues, err, o, "min", true, ParseNumberArrayProperty(&accessor->minValues, err, o, "min", false,
"Accessor")) { "Accessor");
return false;
}
if (!ParseNumberArrayProperty(&accessor->maxValues, err, o, "max", true, ParseNumberArrayProperty(&accessor->maxValues, err, o, "max", false,
"Accessor")) { "Accessor");
return false;
}
accessor->count = static_cast<size_t>(count); accessor->count = static_cast<size_t>(count);
accessor->bufferView = static_cast<int>(bufferView); accessor->bufferView = static_cast<int>(bufferView);