mirror of https://github.com/buggins/dlangui.git
Scene3d: OBJ import
This commit is contained in:
parent
7fc9dd9495
commit
52fbe8a38f
|
@ -0,0 +1,7 @@
|
|||
uniform sampler2D tex;
|
||||
in vec4 col;
|
||||
out vec4 outColor;
|
||||
void main(void)
|
||||
{
|
||||
outColor = col;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
in vec4 vertex;
|
||||
in vec4 colAttr;
|
||||
out vec4 col;
|
||||
uniform mat4 matrix;
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = matrix * vertex;
|
||||
col = colAttr;
|
||||
}
|
|
@ -4,6 +4,8 @@ res/mdpi/cr3_logo.png
|
|||
res/mdpi/tx_fabric.jpg
|
||||
res/mdpi/crate.png
|
||||
res/mdpi/blocks.png
|
||||
res/models/suzanne.obj
|
||||
res/shaders/colored.vert
|
||||
res/shaders/colored.frag
|
||||
res/shaders/textured.vert
|
||||
res/shaders/textured.frag
|
||||
res/models/suzanne.obj
|
||||
|
|
|
@ -22,6 +22,12 @@ struct vec2 {
|
|||
this(float[2] v) {
|
||||
vec = v;
|
||||
}
|
||||
this(float[] v) {
|
||||
vec = v[0..2];
|
||||
}
|
||||
this(float * v) {
|
||||
vec = v[0..2];
|
||||
}
|
||||
this(const vec2 v) {
|
||||
vec = v.vec;
|
||||
}
|
||||
|
@ -258,6 +264,12 @@ struct vec3 {
|
|||
this(float[3] v) {
|
||||
vec = v;
|
||||
}
|
||||
this(float[] v) {
|
||||
vec = v[0..3];
|
||||
}
|
||||
this(float * v) {
|
||||
vec = v[0..3];
|
||||
}
|
||||
this(const vec3 v) {
|
||||
vec = v.vec;
|
||||
}
|
||||
|
@ -1581,3 +1593,13 @@ unittest {
|
|||
m.rotateY(10);
|
||||
m.rotateZ(10);
|
||||
}
|
||||
|
||||
/// calculate normal for triangle
|
||||
vec3 triangleNormal(vec3 p1, vec3 p2, vec3 p3) {
|
||||
return vec3.crossProduct(p2 - p1, p3 - p2).normalized();
|
||||
}
|
||||
|
||||
/// calculate normal for triangle
|
||||
vec3 triangleNormal(float[3] p1, float[3] p2, float[3] p3) {
|
||||
return vec3.crossProduct(vec3(p2) - vec3(p1), vec3(p3) - vec3(p2)).normalized();
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ abstract class GraphicsEffect : RefCountedObject {
|
|||
|
||||
/// vertex element type
|
||||
enum VertexElementType : ubyte {
|
||||
POSITION = 1,
|
||||
POSITION = 0,
|
||||
NORMAL,
|
||||
COLOR,
|
||||
TEXCOORD0,
|
||||
|
@ -40,6 +40,8 @@ enum VertexElementType : ubyte {
|
|||
TEXCOORD7,
|
||||
}
|
||||
|
||||
static assert(VertexElementType.max == VertexElementType.TEXCOORD7);
|
||||
|
||||
/// Graphics primitive type
|
||||
enum PrimitiveType : int {
|
||||
triangles,
|
||||
|
@ -98,21 +100,61 @@ struct VertexElement {
|
|||
/// Vertex format elements list
|
||||
struct VertexFormat {
|
||||
private VertexElement[] _elements;
|
||||
private byte[VertexElementType.max + 1] _elementOffset = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1];
|
||||
private int _vertexSize;
|
||||
/// make using element list
|
||||
this(inout VertexElement[] elems...) {
|
||||
_elements = elems.dup;
|
||||
foreach(elem; elems)
|
||||
foreach(elem; elems) {
|
||||
_elementOffset[elem.type] = cast(byte)(_vertexSize / float.sizeof);
|
||||
_vertexSize += elem.size * float.sizeof;
|
||||
}
|
||||
}
|
||||
/// init from vertex element types, using default sizes for types
|
||||
this(inout VertexElementType[] types...) {
|
||||
foreach(t; types) {
|
||||
_elementOffset[t] = cast(byte)(_vertexSize / float.sizeof);
|
||||
VertexElement elem = VertexElement(t);
|
||||
_elements ~= elem;
|
||||
_vertexSize += elem.size;
|
||||
}
|
||||
}
|
||||
int elementOffset(VertexElementType type) const {
|
||||
return _elementOffset[type];
|
||||
}
|
||||
bool hasElement(VertexElementType type) const {
|
||||
return _elementOffset[type] >= 0;
|
||||
}
|
||||
/// set vec2 component value of vertex
|
||||
void set(float * vertex, VertexElementType type, vec2 value) const {
|
||||
int start = _elementOffset[type];
|
||||
if (start >= 0) {
|
||||
vertex += start;
|
||||
vertex[0] = value.vec[0];
|
||||
vertex[1] = value.vec[1];
|
||||
}
|
||||
}
|
||||
/// set vec3 component value of vertex
|
||||
void set(float * vertex, VertexElementType type, vec3 value) const {
|
||||
int start = _elementOffset[type];
|
||||
if (start >= 0) {
|
||||
vertex += start;
|
||||
vertex[0] = value.vec[0];
|
||||
vertex[1] = value.vec[1];
|
||||
vertex[2] = value.vec[2];
|
||||
}
|
||||
}
|
||||
/// set vec4 component value of vertex
|
||||
void set(float * vertex, VertexElementType type, vec4 value) const {
|
||||
int start = _elementOffset[type];
|
||||
if (start >= 0) {
|
||||
vertex += start;
|
||||
vertex[0] = value.vec[0];
|
||||
vertex[1] = value.vec[1];
|
||||
vertex[2] = value.vec[2];
|
||||
vertex[3] = value.vec[3];
|
||||
}
|
||||
}
|
||||
/// get number of elements
|
||||
@property int length() const {
|
||||
return cast(int)_elements.length;
|
||||
|
@ -170,9 +212,10 @@ class Mesh : RefCountedObject {
|
|||
protected VertexBuffer _vertexBuffer;
|
||||
protected bool _dirtyVertexBuffer = true;
|
||||
|
||||
@property ref const(VertexFormat) vertexFormat() const { return _vertexFormat; }
|
||||
@property ref VertexFormat vertexFormat() { return _vertexFormat; }
|
||||
@property const(VertexFormat) * vertexFormatPtr() { return &_vertexFormat; }
|
||||
|
||||
@property VertexFormat vertexFormat() { return _vertexFormat; }
|
||||
//@property ref VertexFormat vertexFormat() { return _vertexFormat; }
|
||||
|
||||
@property void vertexFormat(VertexFormat format) {
|
||||
assert(_vertexCount == 0);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
module dlangui.graphics.scene.objimport;
|
||||
|
||||
import dlangui.core.logger;
|
||||
import dlangui.core.math3d;
|
||||
import dlangui.dml.tokenizer;
|
||||
import dlangui.graphics.scene.mesh;
|
||||
|
||||
struct ObjModelImport {
|
||||
alias FaceIndex = int[3];
|
||||
|
@ -14,6 +16,9 @@ struct ObjModelImport {
|
|||
private int _triangleCount;
|
||||
private int _txCount;
|
||||
private float[8] _buf;
|
||||
|
||||
MeshRef mesh;
|
||||
|
||||
protected float[] parseFloatList(Token[] tokens, int maxItems = 3, float padding = 0) {
|
||||
int i = 0;
|
||||
foreach(t; tokens) {
|
||||
|
@ -126,7 +131,85 @@ struct ObjModelImport {
|
|||
return true;
|
||||
}
|
||||
|
||||
vec3 vertexForIndex(int index) {
|
||||
if (index < 0)
|
||||
index = _vertexCount + 1 + index;
|
||||
if (index >= 1 && index <= _vertexCount) {
|
||||
index = (index - 1) * 3;
|
||||
return vec3(&_vertexData[index]);
|
||||
}
|
||||
return vec3.init;
|
||||
}
|
||||
|
||||
vec3 normalForIndex(int index) {
|
||||
if (index < 0)
|
||||
index = _normalCount + 1 + index;
|
||||
if (index >= 1 && index <= _normalCount) {
|
||||
index = (index - 1) * 3;
|
||||
return vec3(&_normalData[index]);
|
||||
}
|
||||
return vec3(0, 0, 1);
|
||||
}
|
||||
|
||||
vec2 txForIndex(int index) {
|
||||
if (index < 0)
|
||||
index = _txCount + 1 + index;
|
||||
if (index >= 1 && index <= _txCount) {
|
||||
index = (index - 1) * 2;
|
||||
return vec2(&_txData[index]);
|
||||
}
|
||||
return vec2.init;
|
||||
}
|
||||
|
||||
bool _meshHasTexture;
|
||||
void createMeshIfNotExist() {
|
||||
if (!mesh.isNull)
|
||||
return;
|
||||
if (_txCount) {
|
||||
mesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR, VertexElementType.TEXCOORD0));
|
||||
_meshHasTexture = true;
|
||||
} else {
|
||||
mesh = new Mesh(VertexFormat(VertexElementType.POSITION, VertexElementType.NORMAL, VertexElementType.COLOR));
|
||||
_meshHasTexture = false;
|
||||
}
|
||||
}
|
||||
protected bool addTriangle(FaceIndex v1, FaceIndex v2, FaceIndex v3) {
|
||||
createMeshIfNotExist();
|
||||
float[16 * 3] data;
|
||||
const (VertexFormat) * fmt = mesh.vertexFormatPtr;
|
||||
int vfloats = fmt.vertexFloats;
|
||||
vec3 p1 = vertexForIndex(v1[0]);
|
||||
vec3 p2 = vertexForIndex(v2[0]);
|
||||
vec3 p3 = vertexForIndex(v3[0]);
|
||||
fmt.set(data.ptr, VertexElementType.POSITION, p1);
|
||||
fmt.set(data.ptr + vfloats, VertexElementType.POSITION, p2);
|
||||
fmt.set(data.ptr + vfloats * 2, VertexElementType.POSITION, p3);
|
||||
if (fmt.hasElement(VertexElementType.TEXCOORD0)) {
|
||||
fmt.set(data.ptr, VertexElementType.TEXCOORD0, txForIndex(v1[1]));
|
||||
fmt.set(data.ptr + vfloats, VertexElementType.TEXCOORD0, txForIndex(v2[1]));
|
||||
fmt.set(data.ptr + vfloats * 2, VertexElementType.TEXCOORD0, txForIndex(v3[1]));
|
||||
}
|
||||
if (fmt.hasElement(VertexElementType.COLOR)) {
|
||||
const vec4 white = vec4(1, 1, 1, 1);
|
||||
fmt.set(data.ptr, VertexElementType.COLOR, white);
|
||||
fmt.set(data.ptr + vfloats, VertexElementType.COLOR, white);
|
||||
fmt.set(data.ptr + vfloats * 2, VertexElementType.COLOR, white);
|
||||
}
|
||||
if (fmt.hasElement(VertexElementType.NORMAL)) {
|
||||
vec3 normal;
|
||||
if (!v1[2] || !v2[2] || !v3[2]) {
|
||||
// no normal specified, calculate it
|
||||
normal = triangleNormal(p1, p2, p3);
|
||||
}
|
||||
fmt.set(data.ptr, VertexElementType.NORMAL, v1[2] ? normalForIndex(v1[2]) : normal);
|
||||
fmt.set(data.ptr + vfloats, VertexElementType.NORMAL, v2[2] ? normalForIndex(v2[2]) : normal);
|
||||
fmt.set(data.ptr + vfloats * 2, VertexElementType.NORMAL, v3[2] ? normalForIndex(v3[2]) : normal);
|
||||
}
|
||||
int startVertex = mesh.addVertexes(data.ptr[0 .. vfloats * 3]);
|
||||
mesh.addPart(PrimitiveType.triangles, [
|
||||
cast(ushort)(startVertex + 0),
|
||||
cast(ushort)(startVertex + 1),
|
||||
cast(ushort)(startVertex + 2)]);
|
||||
_triangleCount++;
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue