I want to know how to change the values inside GLKMatrix4.
I mean in static.
If any one knows explain me.If any tutorial to learn or to understand OpenGl reply me with the link... Except raywenderlich tutorial. Because i had already gone through it...
Have you looked at the headers?
#if defined(__STRICT_ANSI__)
struct _GLKMatrix4
{
float m[16];
} __attribute__((aligned(16)));
typedef struct _GLKMatrix4 GLKMatrix4;
#else
union _GLKMatrix4
{
struct
{
float m00, m01, m02, m03;
float m10, m11, m12, m13;
float m20, m21, m22, m23;
float m30, m31, m32, m33;
};
float m[16];
} __attribute__((aligned(16)));
typedef union _GLKMatrix4 GLKMatrix4;
#endif
It varies a bit based on your build environment and target platform/device, but long story short: all of the GLKit math types are plain-old-data structs (or unions), and you can access their members directly.
Related
so it appears that Apple Metal got away with preprocessor directives, opting to use function constants for optionally enabling / disabling parts of shader code.
I can conditionally enable certain struct fields, like so:
constant bool is_cubemap_render [[function_constant(0)]];
struct FragmentOut {
float depth [[depth(any), function_constant(is_cubemap_render)]];
};
However I am having hard time understanding what is the best way to omit a field if is_cubemap_render is false.
struct FragmentOut {
float depth [[depth(any), !function_constant(is_cubemap_render)]]; // does not compile
};
struct FragmentOut {
float depth [[depth(any), function_constant(!is_cubemap_render)]]; // does not compile too
};
What I resorted to doing is
constant bool is_cubemap_render [[function_constant(0)]];
constant bool is_not_cubemap_render = !is_cubemap_render;
struct FragmentOut {
float depth [[depth(any), function_constant(is_cubemap_render)]];
float4 color [[color(0), function_constant(is_not_cubemap_render)]];
};
I don't really like it as it pollutes the start of my files and I have to manually declare new variables. Is there a better way to go about it?
I am passing my metal kernel and shader functions a parameter structure. I can't find anywhere that specifies what Swift data types to use to match the data types in Metal.
I have done my best to guess what data types to use on the Swift side, but it seems to be very picky in what order I define the variables in my structs. Which leads me to believe that they are not aligned.
For instance, here are the data types I am using in Metal:
struct ComputeParameters {
bool yesNo;
int count;
float scale;
float2 point;
float4 color;
};
And here is my corresponding struct in Swift:
struct ComputeParameters {
var yesNo: Bool = false
var count: Int32 = 0
var scale: Float32 = 1.0
var point: float2 = float2(0.0, 0.0)
var color: float4 = float4(0.0, 0.0, 0.0, 1.0)
}
Here is a table of the datatypes I am using from above.
Metal _________ Swift
bool Bool
int Int32
float Float32
float2 float2
float4 float4
Are those correct? Is there somewhere the parameter datatypes are documented?
The size of the Int type in Swift depends on the target platform. It could be equal to Int32 or Int64, though these days it will almost always be Int64. So you should use the more explicit Int32 type to match Metal's 32-bit int type.
As of Swift 5, float2 and float4 are deprecated in favor of SIMD2<Float> and SIMD4<Float>, respectively. These correspond exactly with Metal's float2 and float4.
I believe the rest of your correspondences are correct.
However, it's probably not wise to define these structures in Swift in the first place. Swift gives you no guarantees regarding struct layout (padding, alignment, and member order). Therefore you could wind up with a layout mismatch between Swift and MSL (I haven't seen this happen, but the point is that it can).
The current guidance, I believe, is to define such structs in C/Objective-C instead and import them via a bridging header. That makes it more likely that memcpy-style copies of structs into Metal buffers will do the right thing. Always pay careful attention to size and alignment, especially since manual reordering of struct members can change the size and/or stride of the struct.
I am passing an array of structs to my Metal shader vertex function. The struct looks like this:
struct Vertex {
var x,y,z: Float // position data
var r,g,b,a: Float // color data
var s,t: Float // texture coordinates
var nX,nY,nZ: Float // normal
func floatBuffer() -> [Float] {
return [x,y,z,r,g,b,a,s,t,nX,nY,nZ]
}
};
The floatBuffer function is used to assemble the vertices into one big array of Floats. I am able to pass this into my shader function by using a struct definition which uses "packed" data types, like this:
struct VertexIn {
packed_float3 position;
packed_float4 color;
packed_float2 texCoord;
packed_float3 normal;
};
vertex VertexOut basic_vertex(
const device VertexIn* vertex_array [[ buffer(0) ]],
.
.
.
This works. However, I would like to know how to do the same thing using MTLVertexAttributeDescriptors and the associated syntax. Right now I am getting mangled polygons, presumably because of the byte alignment differences with float3 and packed_float3?
This is how I'm trying to define it now and getting the garbage polygons. I got an error that "packed_float3" is not valid for attributes, so I was trying to figure out how to make regular float3, float4, etc work.
struct VertexIn {
float3 position [[attribute(RayVertexAttributePosition)]];
float4 color [[attribute(RayVertexAttributeColor)]];
float2 texCoord [[attribute(RayVertexAttributeTexCoord)]];
float3 normal [[attribute(RayVertexAttributeNormal)]];
};
class func buildMetalVertexDescriptor() -> MTLVertexDescriptor {
let mtlVertexDescriptor = MTLVertexDescriptor()
var offset = 0
mtlVertexDescriptor.attributes[RayVertexAttribute.position.rawValue].format = MTLVertexFormat.float3
mtlVertexDescriptor.attributes[RayVertexAttribute.position.rawValue].offset = offset
mtlVertexDescriptor.attributes[RayVertexAttribute.position.rawValue].bufferIndex = RayBufferIndex.positions.rawValue
offset += 3*MemoryLayout<Float>.stride
mtlVertexDescriptor.attributes[RayVertexAttribute.color.rawValue].format = MTLVertexFormat.float4
mtlVertexDescriptor.attributes[RayVertexAttribute.color.rawValue].offset = offset
mtlVertexDescriptor.attributes[RayVertexAttribute.color.rawValue].bufferIndex = RayBufferIndex.positions.rawValue
offset += MemoryLayout<float4>.stride
mtlVertexDescriptor.attributes[RayVertexAttribute.texCoord.rawValue].format = MTLVertexFormat.float2
mtlVertexDescriptor.attributes[RayVertexAttribute.texCoord.rawValue].offset = offset
mtlVertexDescriptor.attributes[RayVertexAttribute.texCoord.rawValue].bufferIndex = RayBufferIndex.positions.rawValue
offset += MemoryLayout<float2>.stride
mtlVertexDescriptor.attributes[RayVertexAttribute.normal.rawValue].format = MTLVertexFormat.float3
mtlVertexDescriptor.attributes[RayVertexAttribute.normal.rawValue].offset = offset
mtlVertexDescriptor.attributes[RayVertexAttribute.normal.rawValue].bufferIndex = RayBufferIndex.positions.rawValue
offset += 3*MemoryLayout<Float>.stride
print("stride \(offset)")
mtlVertexDescriptor.layouts[RayBufferIndex.positions.rawValue].stride = offset
mtlVertexDescriptor.layouts[RayBufferIndex.positions.rawValue].stepRate = 1
mtlVertexDescriptor.layouts[RayBufferIndex.positions.rawValue].stepFunction = MTLVertexStepFunction.perVertex
return mtlVertexDescriptor
}
Notice that I specify the first attribute as a float3, but I specify an offset of 3 floats instead of the 4 that a float3 would normally use. But it isn't enough, apparently. I'm wondering how to set up a MTLVertexDescriptor and the shader struct with attributes so that it handles the 'packed' data from my structs?
Thanks very much.
The key is in this part of your question: "Notice that I specify the first attribute as a float3, but I specify an offset of 3 floats instead of the 4 that a float3 would normally use".
The SIMD float3 type takes up 16 bytes, it has the same memory layout as the non-packed Metal float3 type. So when you set the offset to only 3*MemoryLayout.stride you are missing the last 4 bytes which are still present causing the next field to pull from those extra bytes and for the rest of the data to be offset.
To really use packed types to transfer data to Metal (or any graphics API) you either have to stick with what you were doing before and specify x, y, z in three separate Floats in an array, or you have to define your own struct like this:
struct Vector3 {
var x: Float
var y: Float
var z: Float
}
Swift doesn't have any guarantees that this struct will be three Floats packed closely together, but for now and the foreseeable future it works and will be 12 bytes in size on most platforms.
If you want to be able to do vector operations on a struct like this then I would suggest looking for a library that defines types like these to save yourself some time as you will run into the same types of problems with 3x3 matrices also.
I ran into the same problems so I ended up rolling my own:
https://github.com/jkolb/Swiftish
Is it possible, using XNA 4, to include a Shader within another shader? I know you could do this within 3.1, but I seem to be having trouble getting this to work? If you can, any pointers would be great.
EDIT
//---------------------------------------------------------------------------//
// Name : Rain.fx
// Desc : Rain particle effect using cylindrical billboards
// Author : Justin Stoecker. Copyright (C) 2008-2009.
//---------------------------------------------------------------------------//
#include "common.inc" // It's this line that causes me a problem
float4x4 matWorld;
float3 vVelocity;
float3 vOrigin; // min point of the cube area
float fWidth; // width of the weather region (x-axis)
float fHeight; // height of the weather region (y-axis)
float fLength; // length of the weather region (z-axis)
... Rest of file ...
The "common.inc" file has variables in there, but I was wondering if you could put methods in there as well?
Yes it's possible, from memory I think the basic effect example shader example from the MS App Hub does it.
In any case, see code below!
In FractalBase.fxh
float4x4 MatrixTransform : register(vs, c0);
float2 Pan;
float Zoom;
float Aspect;
float ZPower = 2;
float3 Colour = 0;
float3 ColourScale = 0;
float ComAbs(float2 Arg)
{
}
float2 ComSquare(float2 Arg)
{
}
int GreaterThan(float x, float y)
{
}
float4 GetColour(int DoneIterations, float MaxIterations, float BailoutTest, float OldBailoutTest, float BailoutFigure)
{
}
void SpriteVertexShader(inout float4 Colour : COLOR0,
inout float2 texCoord : TEXCOORD0,
inout float4 position : SV_Position)
{
position = mul(position, MatrixTransform);
// Convert the position into from screen space into complex coordinates
texCoord = (position) * Zoom * float2(1, Aspect) - float2(Pan.x, -Pan.y);
}
In FractalMandelbrot.fx
#include "FractalBase.fxh"
float4 FractalPixelShader(float2 texCoord : TEXCOORD0, uniform float Iterations) : COLOR0
{
}
technique Technique1
{
pass
{
VertexShader = compile vs_3_0 SpriteVertexShader();
PixelShader = compile ps_3_0 FractalPixelShader(128);
}
}
#includes work like this:
The preprocessor loads your main .fx file, and parses it, looking for anything that starts with a #. #includes cause the preprocessor to load the referenced file and insert its contents into the source buffer. Effectively, your #include directive is replaced by the entire contents of the included file.
So, yes, you can define anything in your #includes that you can define in a regular .fx file. I use this for keeping lighting functions, vertex type declarations, etc in common files that are used by several shaders.
I'm trying to read 3D models which were created for a DirectX applications, which are defined in the following way :
In the file header, the Flexible Vertex Format (FVF) of the mesh is given (actually, I have any combinations of D3DFVF_{XYZ,DIFFUSE,NORMAL,TEX1,TEX2} in the meshes I tested)
Then, n vertices are given in a linear pattern, with the fields presents according to the FVF.
However, I do not know the order of these fields. The logic would be that it is defined somewhere in DirectX documentation, but I was unable to find it. For example, which of these two structures is correct with FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL (C syntax, but this problem applies to every language) ?
// This one ?
struct vertex1
{
D3DVERTEX pos;
DWORD color;
D3DVERTEX normal;
};
// Or this one ?
struct vertex2
{
D3DVERTEX pos;
D3DVERTEX normal;
DWORD color;
};
I would like a general answer to this question with all the possible fields (for example, XYZ before DIFFUSE before NORMAL before TEX1 before TEX2). A pointer to the right page of the documentation would be fine too as I was not able to find it :) .
I ran into the same thing myself.
I think the order of the bits is the required order. From d3d9types.h:
#define D3DFVF_RESERVED0 0x001
#define D3DFVF_POSITION_MASK 0x400E
#define D3DFVF_XYZ 0x002
#define D3DFVF_XYZRHW 0x004
#define D3DFVF_XYZB1 0x006
#define D3DFVF_XYZB2 0x008
#define D3DFVF_XYZB3 0x00a
#define D3DFVF_XYZB4 0x00c
#define D3DFVF_XYZB5 0x00e
#define D3DFVF_XYZW 0x4002
#define D3DFVF_NORMAL 0x010
#define D3DFVF_PSIZE 0x020
#define D3DFVF_DIFFUSE 0x040
#define D3DFVF_SPECULAR 0x080
#define D3DFVF_TEXCOUNT_MASK 0xf00
#define D3DFVF_TEXCOUNT_SHIFT 8
#define D3DFVF_TEX0 0x000
#define D3DFVF_TEX1 0x100
#define D3DFVF_TEX2 0x200
#define D3DFVF_TEX3 0x300
#define D3DFVF_TEX4 0x400
#define D3DFVF_TEX5 0x500
#define D3DFVF_TEX6 0x600
#define D3DFVF_TEX7 0x700
#define D3DFVF_TEX8 0x800
I'm pretty sure that the order you are looking for is:
POSITION,NORMAL,PSIZE,DIFFUSE,SPECULAR,TEX0[,TEXn...]
I wasn't able to find a definitive answer in the documentation either.
here you are
FVF (OP says the information on this page is incorrect. I dont know, didnt check if FVF positioning is correct)
Generator
Well you should be defining it as follows.
struct EitherVertex
{
float x, y, z;
DWORD col;
float nx, ny, nz
};
or
struct EitherVertex
{
D3DXVECTOR3 pos;
DWORD col;
D3DXVECTOR3 nrm;
};
(D3DVERTEX refers to an entire vertex struct and not just a 3 element vector)
Of your 2 options a lot depends on how you access those vert elements. If you are using the depreceated FVF then the second of your 2 choice is the more correct.
If however you are using Vertex Declarations then YOU define where in the struct the relevant data is and the ordering does not matter.