/// <summary> /// Find fragments in the specified triangle. /// </summary> /// <param name="fragCoord0"></param> /// <param name="fragCoord1"></param> /// <param name="fragCoord2"></param> /// <param name="pointers"></param> /// <param name="group"></param> /// <param name="passBuffers"></param> /// <param name="result"></param> unsafe private static void FindFragmentsInTriangle(vec3 fragCoord0, vec3 fragCoord1, vec3 fragCoord2, void *[] pointers, LinearInterpolationInfoGroup group, PassBuffer[] passBuffers, List <Fragment> result) { int attributeCount = passBuffers.Length - 1; var pixelList = new List <vec3>(); FindPixelsAtTriangle(fragCoord0, fragCoord1, fragCoord2, pixelList); //OnSamePlane(fragCoord0, fragCoord1, fragCoord2, pixelList); for (int i = 0; i < pixelList.Count; i++) // for each pixel at this line.. { vec3 pixel = pixelList[i]; var fragment = new Fragment(pixel, attributeCount); float p0, p1, p2; LinearInterpolationTriangle(pixel, fragCoord0, fragCoord1, fragCoord2, out p0, out p1, out p2); for (int t = 0; t < attributeCount; t++) // new pass-buffer objects. { PassType passType = passBuffers[t + 1].elementType; fragment.attributes[t] = new PassBuffer(passType, 1); // only one element. } for (int attrIndex = 0; attrIndex < attributeCount; attrIndex++) // fill data in pass-buffer. { PassBuffer attribute = fragment.attributes[attrIndex]; void * fragmentAttribute = attribute.Mapbuffer().ToPointer(); switch (attribute.elementType) { case PassType.Float: { var fAttr = (float *)fragmentAttribute; var array = (float *)pointers[attrIndex]; fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2; } break; case PassType.Vec2: { var fAttr = (vec2 *)fragmentAttribute; var array = (vec2 *)pointers[attrIndex]; fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2; } break; case PassType.Vec3: { var fAttr = (vec3 *)fragmentAttribute; var array = (vec3 *)pointers[attrIndex]; fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2; } break; case PassType.Vec4: { var fAttr = (vec4 *)fragmentAttribute; var array = (vec4 *)pointers[attrIndex]; fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2; } break; case PassType.Mat2: { var fAttr = (mat2 *)fragmentAttribute; var array = (mat2 *)pointers[attrIndex]; fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2; } break; case PassType.Mat3: { var fAttr = (mat3 *)fragmentAttribute; var array = (mat3 *)pointers[attrIndex]; fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2; } break; case PassType.Mat4: { var fAttr = (mat4 *)fragmentAttribute; var array = (mat4 *)pointers[attrIndex]; fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2; } break; default: throw new NotDealWithNewEnumItemException(typeof(PassType)); } attribute.Unmapbuffer(); } result.Add(fragment); } }
private unsafe List <Fragment> LinearInterpolationPoints(int count, DrawElementsType type, IntPtr indices, VertexArrayObject vao, ShaderProgram program, GLBuffer indexBuffer, PassBuffer[] passBuffers) { var result = new List <Fragment>(); int attributeCount = passBuffers.Length - 1; var gl_PositionArray = (vec4 *)passBuffers[0].Mapbuffer().ToPointer(); var pointers = new void *[passBuffers.Length - 1]; for (int i = 0; i < pointers.Length; i++) { pointers[i] = passBuffers[i + 1].Mapbuffer().ToPointer(); } byte[] indexData = indexBuffer.Data; int indexLength = indexData.Length / ByteLength(type); GCHandle pin = GCHandle.Alloc(indexData, GCHandleType.Pinned); IntPtr pointer = pin.AddrOfPinnedObject(); var gl_VertexIDList = new List <uint>(); ivec4 viewport = this.viewport; for (int indexID = indices.ToInt32() / ByteLength(type), c = 0; c < count && indexID < indexLength; indexID++, c++) { uint gl_VertexID = GetVertexID(pointer, type, indexID); if (gl_VertexIDList.Contains(gl_VertexID)) { continue; } else { gl_VertexIDList.Add(gl_VertexID); } vec3 fragCoord = new vec3((gl_PositionArray[gl_VertexID].x + 1) / 2.0f * viewport.z + viewport.x, (gl_PositionArray[gl_VertexID].y + 1) / 2.0f * viewport.w + viewport.y, (gl_PositionArray[gl_VertexID].z + 1) / 2.0f * (float)(this.depthRangeFar - this.depthRangeNear) + (float)this.depthRangeNear); var fragment = new Fragment(fragCoord, attributeCount); for (int i = 0; i < attributeCount; i++) // new pass-buffer objects. { PassType passType = passBuffers[i].elementType; fragment.attributes[i] = new PassBuffer(passType, 1); // only one element. } for (int attrIndex = 0; attrIndex < attributeCount; attrIndex++) // fill data in pass-buffer. { PassBuffer attribute = fragment.attributes[attrIndex]; void * fragmentAttribute = attribute.Mapbuffer().ToPointer(); switch (attribute.elementType) { case PassType.Float: { var fAttr = (float *)fragmentAttribute; var array = (float *)pointers[attrIndex]; fAttr[0] = array[gl_VertexID]; } break; case PassType.Vec2: { var fAttr = (vec2 *)fragmentAttribute; var array = (vec2 *)pointers[attrIndex]; fAttr[0] = array[gl_VertexID]; } break; case PassType.Vec3: { var fAttr = (vec3 *)fragmentAttribute; var array = (vec3 *)pointers[attrIndex]; fAttr[0] = array[gl_VertexID]; } break; case PassType.Vec4: { var fAttr = (vec4 *)fragmentAttribute; var array = (vec4 *)pointers[attrIndex]; fAttr[0] = array[gl_VertexID]; } break; case PassType.Mat2: { var fAttr = (mat2 *)fragmentAttribute; var array = (mat2 *)pointers[attrIndex]; fAttr[0] = array[gl_VertexID]; } break; case PassType.Mat3: { var fAttr = (mat3 *)fragmentAttribute; var array = (mat3 *)pointers[attrIndex]; fAttr[0] = array[gl_VertexID]; } break; case PassType.Mat4: { var fAttr = (mat4 *)fragmentAttribute; var array = (mat4 *)pointers[attrIndex]; fAttr[0] = array[gl_VertexID]; } break; default: throw new NotDealWithNewEnumItemException(typeof(PassType)); } attribute.Unmapbuffer(); } result.Add(fragment); } for (int i = 0; i < passBuffers.Length; i++) { passBuffers[i].Unmapbuffer(); } return(result); }