text:
Surgical adverse outcome reporting as part of routine clinical care
J Kievit1,2,3,4,
M Krukerink1,
P J Marang-van de Mheen1,3,4
1Department of Medical Decision Making, Leiden University Medical Centre, The Netherlands
2Department of Surgery, Leiden University Medical Centre, The Netherlands
3Association of Surgeons of the Netherlands, Utrecht, The Netherlands
4Order of Medical Specialists, Utrecht, The Netherlands
Correspondence to Prof Dr Job Kievit, Department of Surgery, Department of Medical Decision Making, Leiden University Medical Centre, J10-S, PO Box 9600, 2300 RC Leiden, The Netherlands; j.kievit{at}lumc.nl
Background In The Netherlands, health professionals have created a doctor-driven standardised system to report and analyse adverse outcomes (AO). The aim is to improve healthcare by learning from past experiences. The key elements of this system are (1) an unequivocal definition of an adverse outcome, (2) appropriate contextual information and (3) a three-dimensional hierarchical classification system.
Objectives First, to assess whether routine doctor-driven AO reporting is feasible. Second, to investigate how doctors can learn from AO reporting and analysis to improve the quality of care.
Methods Feasibility was assessed by how well doctors reported AO in the surgical department of a Dutch university hospital over a period of 9 years. AO incidence was analysed per patient subgroup and over time, in a time-trend analysis of three equal 3-year periods. AO were analysed case by case and statistically, to learn lessons from past events.
Results In 19 907 surgical admissions, 9189 AOs were reported: one or more AO in 18.2% of admissions. On average, 55 lessons were learnt each year (in 4.3% of AO). More AO were reported in P3 than P1 (OR 1.39 (1.23–1.57)). Although minor AO increased, fatal AO decreased over time (OR 0.59 (0.45–0.77)).
Conclusions Doctor-driven AO reporting is shown to be feasible. Lessons can be learnt from case-by-case analyses of individual AO, as well as by statistical analysis of AO groups and subgroups (illustrated by time-trend analysis), thus contributing to the improvement of the quality of care. Moreover, by standardising AO reporting, data can be compared across departments or hospitals, to generate (confidential) mirror information for professionals cooperating in a peer-review setting.
Adverse-effect
adverse-outcome
quality assurance, healthcare
lessons learnt
surgical context
This is an open-access article distributed under the terms of the Creative Commons Attribution Non-commercial License, which permits use, distribution, and reproduction in any medium, provided the original work is properly cited, the use is non commercial and is otherwise in compliance with the license. See: http://creativecommons.org/licenses/by-nc/2.0/ and http://creativecommons.org/licenses/by-nc/2.0/legalcode.
http://dx.doi.org/10.1136/qshc.2008.027458
Most studies on medical adverse outcomes (AO) rely on retrieval and reconstruction of events from patients' records by trained reviewers.1–6 Such approaches have limited effectiveness for quality assessment and improvement. First, retrospective retrieval suffers from the fact that valuable contextual information may be lost when data collection occurs long after the actual medical treatment. Second, older studies often focus on negligence or the type of injury inflicted, and not on learning from past events.2 ,3 ,5 ,7
What is needed, and cannot be delivered by retrospective studies, is a system that encourages healthcare providers to report AOs routinely and then gives immediate and meaningful feedback by which doctors can learn from past events. With these aims in mind, the Dutch Order of Medical Specialists set nationwide standards to create a doctor-driven system of AO reporting that is integrated into routine clinical care. Its key elements are (1) an unambiguous definition of what constitutes an AO, (2) a minimum set of contextual data needed for analysis, and (3) a classification system that organises AOs into clinically and causally relevant groups and subgroups.
The present study elucidates the principles and methods of this system, assesses its advantages and limitations and illustrates its clinical use in the surgical department of a Dutch university hospital.
A standardised AO reporting system has been in use at the Department of Surgery of the Leiden University Medical Centre since 1997. It is used on all patients who were admitted to, or under the responsibility of, the Department of Surgery, and on patients admitted to non-surgical departments who were operated by a surgeon (or an intern or a resident). Each weekend, a software routine of the Leiden University Medical Centre hospital information system retrieves patients meeting the above surgical criteria who had been discharged in the week that ended 2 weeks before that weekend. The surgical procedures that these patients underwent cover the whole of general surgery, ranging from endocrine, gastrointestinal, oncological, transplant, trauma, to vascular surgery.
Definition of adverse outcome
In The Netherlands, an "adverse outcome" is defined as: "… an unintended and unwanted event or state occurring during or following medical care, that is so harmful to a patient's health that (adjustment of) treatment is required or that permanent damage results. The adverse outcome may be noted during treatment or in a predefined period after discharge or transfer to another department. The intended results of treatment, the likelihood of the adverse outcome occurring and the presence or absence of a medical error causing it, are irrelevant in identifying an adverse outcome."
The Dutch definition of an AO is more sensitive than the definitions used in retrospective studies in that those definitions excluded the consequences of the disease itself and/or co-morbidity.1–3 Using a definition with such exclusion rules in routine reporting would require a doctor to completely understand the cause of an AO and its preventability and/or blame. The Dutch definition obviates such judgement, with the aim of reducing subjectivity and inter-observer variability and thereby facilitating comparisons over time and/or across different settings.
Management of (contextual) information
A special software was designed to support the management of hospital information system and AO data. All the patients identified by the hospital information system search were automatically imported each week into an AO database (Access 2003) with a minimum dataset of contextual information, including name, gender, date of birth, operative procedures performed and the American Society of Anesthesiologists (ASA) classification. Operative procedures were automatically classified with respect to technical complexity, according to the standards of the Association of Surgeons of The Netherlands (on a scale ranging from 1 for simple to 5–7 for complex or difficult surgical procedures).
The occurrence or non-occurrence of all AO was recorded on paper for all patients. Selected AOs were checked and discussed at weekly meetings attended by surgeons, residents and interns and chaired by a staff surgeon. The selection of AOs was based on an algorithm that included patients (1) with three or more AOs, (2) with one or more AOs leading to reoperation, permanent damage and/or death (ie, grade 2 or higher; see below) or (3) with an AO report that seemed likely to contain a lesson for the future. The aim of the above selection was to ensure interesting meetings and thus maximise attendance. Each patient with an AO was presented by the intern/resident who was on the ward when the patient was discharged. The focus of the ensuing discussion was to interpret the underlying causes and thus learn how other such outcomes might be prevented. After the meeting, data forms of all patients, without and with AOs, discussed and non-discussed, are entered into the AO database using the software described above. Patients with one or more AOs are the denominator of the proportion of patients with an AO, the whole patient set being the numerator.
Master classification
AOs were classified according to a special classification system that was designed to match existing (inter)national classification systems as closely as possible. This "master classification" facilitated analysis by allowing AO to be automatically aggregated (by the software) into specific groups and subgroups, The master classification system defines the key characteristics of each AO in terms of the following three dimensions (see Online Appendix A):
Type of AO that is its pathology (eg, infection, bleeding)
Location, specified by
a. region (eg, thorax, abdomen) and/or by
b. organ or organ system (eg, lung, liver) and/or by
c. tissue
Contextual information and potential determinants (eg, medication).
The first dimension—type—is based on the International Classification of Diseases, 10th revision, but with adaptations to accommodate AOs (as opposed to spontaneous disease). The second dimension—location—is based on the Dutch WCC Standard Anatomical Location (http://www.rivm.nl/who-fic/Annuals/Paris26.pdf), developed by WHO. Of the various elements that fall under contextual information dimension, the coding of medication was derived from the Anatomical Therapeutic Chemical classification (http://www.whocc.no/atc_ddd_publications/guidelines/). Each dimension comprises two or more degrees of detail, to allow general and detailed analyses. AOs were graded according to four levels of severity: (1) temporary health disadvantage, recovery without (re)operation; (2) recovery after (re)operation; (3) (probably) permanent damage or function loss; and (4) death.
AOs were analysed in two ways: by discussion of individual patients at weekly AO meetings and by regular statistical analysis of patient groups and subgroups.
Individual patients were discussed at by means of four structured questions shown below (table 1). The answers given provided (interpretational) information on determinants and preventability. All answers generated since 2003 have been stored in a second database. Lessons learnt can lead to quality improvement on for individual patients and for similar patients in the future.
The statistical analysis of the groups and subgroups was performed at regular intervals, at least once a year or whenever deemed necessary—for example, a clinical query or a research question. Logistic regression analysis was used to study the relation between patient mix and operation mix on the one hand, and the incidence of (admissions with) AOs on the other. Patient-mix characteristics were age at admission, gender, and anaesthetic risk profile (high risk being defined as ASA 3 or higher at first operation).6 ,8 The operation mix consisted of various degrees of surgical technical complexity or difficulty.
The four main questions that guide weekly discussions on adverse outcomes
For the analysis of time trends, the total study period of 9 years was subdivided into three equal periods (P1: 1997–1999, P2: 2000–2002 and P3: 2003–2005), which allowed for a more robust analysis than analysis per year. Logistic regression analysis was carried out for all 18 types of AOs and for each of the four grades of severity. The number of AOs per subset divided by the number of all AOs was taken to be an indicator of a subset's contribution to the overall trend. If the incidence of a specific type of AO changed/increased significantly over time to such an extent that it contributed more than 5% of all AOs, further analysis was performed to identify which subgroups within that category, defined on the second or third dimension, contributed most to the observed time trend.
In all analyses, significance was determined by p values smaller than 0.01, given the large number of patient admissions.
Over the 9-year study period, 19 907 patient admissions met the inclusion criteria for surgical AO reporting. For all these admissions, the absence or occurrence of AOs was documented and verified. Mean patient age at admission was 46.7 (21.9) years, 47.5% of patients were women, 18.5% were ASA 3 or higher and 29.9% underwent "complex" surgery (see table 2). A total of 9189 AOs were reported, with one or more AOs occurring in 18.2% of admissions (table 2).
Data on patient admissions for surgery, operations and adverse outcomes (Leiden University Medical Centre, 1997–2005)
Just under half of all AOs (44.5%) were discussed at weekly meetings. Most AOs were deemed to be related to operative treatment (42.5%), followed by non-surgical treatment (29.4%), primary disease (14.5%) and co-morbidity (13.5%). From 2003 to 2005 (P3), 20.9% of all AOs were considered (potentially) avoidable and 4.3% led to specific "lessons learnt"; that is, an average of 55 lessons per year.
Older patients had more AOs, as did high-risk patients and patients undergoing complex surgery (table 3). The overall incidence of reported AOs increased over time (table 3), AO incidence being 39% higher in P3 than in P1, mainly because of an increase in minor AOs (severity category 1, see table 4). The incidence of AOs of severity category 4 (death of the patient) decreased by 40% between 1997 and 2005.
Incidence of registered adverse outcomes in surgical patients over time
Severity of adverse outcome in three periods (1997–1999, 2000–2002 and 2003–2005)
Investigation of AO types showed that 7 out of 18 main-type categories occurred more frequently in P2 and/or P3 than in P1. The two categories that occurred most frequently (indicated in bold in table 5) were "inflammation/infection" and "functional disorders" (29% and 23%, respectively; other categories only 7%).
Type of adverse outcome in three periods (1997–1999, 2000–2002 and 2003–2005)*
Investigation of AO location showed that AOs of the abdomen, leg (table 6) and circulatory tract (table 7) contributed most to the observed increase in "inflammation/infection". Investigation of the third dimension—context—revealed that wound infections increased significantly (odds ratio (OR) 1.54 (1.20–1.98) for P3 vs P1) and accounted for 27% of the overall infection increase. Circulatory tract infections, in particular those related with the use of vascular catheters, likewise increased (OR 2.97 (1.51–5.82) in P3 compared with P1) but contributed only 4.4%.
Body regions with infections in three periods (1997–1999, 2000–2002 and 2003–2005)
Organ systems with infections in three periods (1997–1999, 2000–2002 and 2003–2005)
The increase in "functional disorders" was mainly explained by a significant increase in functional disorders of the kidney (OR 2.32 (1.52–3.52) for P3 vs P1, and contributing 12.8% of functional disorders), and by medication-related functional disorders (OR 2.32 (1.06–5.06) for P3 vs P1).
The present study demonstrates that doctor-driven reporting of AO is feasible alongside routine clinical care over a long period. Even after adjusting for shifts in patient mix and operation mix, it was seen that the number of non-serious AO reported increased rather than decreased, whereas the number of deaths (severity 4 AO) decreased. This suggests that the reporting of AO has become increasingly sensitive over time and that surgical care has become safer with respect to mortality. AO reporting was used to support professionals in assessing and improving their own quality of care in two ways. First, through the weekly AO meetings, surgeons discuss and analyse AOs that their patients suffered case by case. The emphasis lies on 'What can we learn from this?' instead of on 'What have they done wrong?'. The lessons learnt in this way averaged 55 per year in the third period, and applied to many areas ranging from thrombosis prophylaxis in subgroups of patients to technicalities of fracture management at the operating room, and from the appropriate use of antibiotics in trauma patients to timing and preoperative workup of liver transplant patients. Second, at a group level, the aggregation of AOs into master classification groups makes it possible to carry out a statistical analysis of AOs and possible determinants, independent of the weekly case-by-case analyses. As an example, the time-trend analysis presented here demonstrates a significant increase in functional disorders of the kidney, which is most likely related to new immune-modulating drugs used in transplantation and an increase in reported infections. A detailed analysis of the latter has been published in a separate paper.9 Infections identified by AO reporting differ from those identified by monitoring of the Centers for Disease Control and Prevention, as AO reporting includes all suspected or proven infections that do not resolve without treatment, that is, that require(d) treatment or have been treated. Apart from the fact that infection monitoring by the Centers for Disease Control and Prevention is not ubiquitous in all Dutch hospitals, it does not routinely provide detailed information on context or potential causes.
Outside the context of the registering department or hospital, doctor-driven AO reporting can also be used for "mutual monitoring". When professionals from different departments or hospitals cooperate through a (confidential) national AO database, this can provide mirror information to allow doctors to compare their own AO data with anonymous AO data that have been collected by professionals working in similar hospitals or departments. For such a purpose, the system described here has been adopted as the national standard for AO reporting by the Association of Surgeons of The Netherlands. Obviously, additional important issues will need to be addressed, such as adjusting for under-reporting and for more detailed differences in patient and operation mix, to further improve the validity of mirror comparisons.
The Dutch Healthcare Inspectorate analyses the quality of care of all Dutch hospitals annually through national "external" benchmarking of a set of 20 quality performance indicators. One of these indicators is whether medical professionals and hospital departments practice AO reporting. The Inspectorate has, in line with recommendation 6.1 of the Institute of Medicine report "To err is human"i on peer-review protections, stated that AO data are and will at all times remain the sole property of the medical professionals and will never directly be used for benchmarking. However, if professionals are found to have out-of-range performance indicators, they themselves can use the detailed information provided by the AO reporting system to bring their performance up to standard.
Other research has been published on how to make healthcare safer.10–12 Chang et al13 proposed a standardised terminology and classification for adverse events. The approach presented here differs from Chang et al's in that it is not limited to outcomes that are related to errors in the medical (management) process. By eliminating causality, such as errors, as a criterion for reporting, the "Dutch approach" is more sensitive and has less observer-dependent reporting. In addition, it provides information about all AO and is thus a more relevant source of information because it does not exclude AOs that are not caused by errors. The fact that Dutch AO reporting is integrated into routine clinical practice has advantages over other initiatives that are not rooted in routine patient management, such as the National Confidential Enquiry into Patient Outcome and Death.14 ,15 Not the least of these advantages are the regular plenary discussions among clinicians and the lessons learnt directly each week.
Doctor-driven reporting inevitably has drawbacks as well, the most obvious being underreporting. However, we have shown in an earlier study that, with the overriding focus on learning, underreporting can be kept to a minimum.
The internal monitoring described here, and the mutual monitoring, which is presently part of an initiative in The Netherlands, demonstrate that doctor-driven AO reporting can be a powerful instrument with the potential to prevent AO in patients in the future.
The definition and the classification system presented here, after being pioneered at the Department of Surgery at the Academic Hospital Leiden in the 1980s by the first author (JK), have benefited from more than two decades of input from many individuals and organisations, including the Association of Surgeons of The Netherlands, the Committee on Adverse Outcome Reporting of the Order of Medical Specialists and Prismant (http://www.Prismant.nl). Their important contributions are gratefully acknowledged. Further information can be obtained from the Order of Medical Specialists, Utrecht, The Netherlands (http://orde.artsennet.nl/), or through the authors. Finally, the authors gratefully acknowledge the editorial help of Mrs Petry Kievit-Tyson.
Brennan TA,
Leape LL,
Laird NM,
. Incidence of adverse events and negligence in hospitalized patients. Results of the Harvard Medical Practice Study I. N Engl J Med 1991;324:370–6.
Gawande AA,
Thomas EJ,
Zinner MJ,
. The incidence and nature of surgical adverse events in Colorado and Utah in 1992. Surgery 1999;126:66–75.
Kable AK,
Gibberd RW,
Spigelman AD
. Adverse events in surgical patients in Australia. Int J Qual Health Care 2002;14:269–76.
Davis P,
Lay-Yee R,
Briant R,
. Adverse events in New Zealand public hospitals II: preventability and clinical context. N Z Med J 2003;116:U624.
. Adverse events in New Zealand public hospitals I: occurrence and impact. N Z Med J 2002;115:U271.
Wolters U,
Wolf T,
Stutzer H,
. ASA classification and perioperative variables as predictors of postoperative outcome. Br J Anaesth 1996;77:217–22.
Garbutt J,
Waterman AD,
Kapp JM,
. Lost opportunities: how physicians communicate about medical errors. Health Aff (Millwood) 2008;27:246–55.
American Society for Anesthesiology. New classification of physical status. Anesthesiology 1963;24:111.
Krukerink M,
Kievit J,
Marang-van de Mheen PJ
. Evaluation of routinely reported surgical site infections against microbiological culture results: a tool to identify patient groups where diagnosis and treatment may be improved. BMC Infect Dis 2009;9:176.
Barach P,
Johnson JK
. Understanding the complexity of redesigning care around the clinical microsystem. Qual Saf Health Care 2006;15(Suppl 1):i10–6.
Dunn W,
Murphy JG
. Simulation: about safety, not fantasy. Chest 2008;133:6–9.
Davidoff F,
Batalden P,
Stevens D,
. Publication guidelines for quality improvement in health care: evolution of the SQUIRE project. Qual Saf Health Care 2008;17(Suppl 1):i3–9.
Chang A,
Schyve PM,
Croteau RJ,
. The JCAHO patient safety event taxonomy: a standardized terminology and classification schema for near misses and adverse events. Int J Qual Health Care 2005;17:95–105.
Nixon SJ
. NCEPOD: revisiting perioperative mortality. BMJ 1992;304:1128–9.
NCEPOD National Confidential Enquiry into Perioperative Deaths. Health Serv Manage 1990;86:203.
Web Only Data qshc.2008.027458
Files in this Data Supplement:
View Supplementary Tables
Funding Over the years funding for the nationwide development of the surgical adverse outcome registration was obtained from the Health Research and Development Council ZONMW (by grant number 16450001), from the Association of Surgeons of The Netherlands, and from the Order of Medical Specialists.
↵i See Recommendation 6.1. Congress should pass legislation to extend peer-review protections to data related to patient safety and quality improvement that are collected and analysed by healthcare organisations for internal use or shared with others solely for purposes of improving safety and quality.
© 2010, Published by the BMJ Publishing Group Limited. For permission to use (where not already granted under a licence) please go to http://group.bmj.com/group/rights-licensing/permissions. This is an open-access article distributed under the terms of the Creative Commons Attribution Non-commercial License, which permits use, distribution, and reproduction in any medium, provided the original work is properly cited, the use is non commercial and is otherwise in compliance with the license. See: http://creativecommons.org/licenses/by-nc/2.0/ and http://creativecommons.org/licenses/by-nc/2.0/legalcode.


text:
// Copyright (c) 2013 Justin Stenning
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using SharpDX;
using SharpDX.Windows;
using SharpDX.DXGI;
using SharpDX.Direct3D11;
using SharpDX.D3DCompiler;

using Common;

// Resolve class name conflicts by explicitly stating
// which class they refer to:
using Buffer = SharpDX.Direct3D11.Buffer;

namespace Ch09_02DynamicCubeMapping
{
    public class D3DApp : Common.D3DApplicationDesktop
    {
        // The vertex shader
        VertexShader vertexShader;

        // The pixel shader
        //PixelShader pixelShader;

        // A pixel shader that renders the depth (black closer, white further away)
        //PixelShader depthPixelShader;

        // The lambert shader
        //PixelShader lambertShader;

        // The Blinn-Phong shader
        PixelShader blinnPhongShader;

        // The Phong shader
        //PixelShader phongShader;

        // The vertex layout for the IA
        InputLayout vertexLayout;

        // Our configured depth stencil state
        DepthStencilState depthStencilState;

        // A buffer that will be used to update the worldViewProjection
        // constant buffer of the vertex shader
        Buffer perObjectBuffer;

        // A buffer that will be used to update the lights
        Buffer perFrameBuffer;

        // A buffer that will be used to update object materials
        Buffer perMaterialBuffer;

        // A buffer that will be used to update object armature/skeleton
        Buffer perArmatureBuffer;

        // Shaders to create environment map
        GeometryShader envMapGSShader;
        VertexShader envMapVSShader;
        PixelShader envMapPSShader;
        RasterizerState rasterizerState;

        // List of contexts
        DeviceContext[] contextList;
        int threadCount = 1;
        int additionalCPULoad = 0;
        int maxReflectors = 1;
        bool buildCubeMapGeometryInstancing = true;

        public D3DApp(System.Windows.Forms.Form window) : base(window) { }

        protected override SwapChainDescription1 CreateSwapChainDescription()
        {
            var description = base.CreateSwapChainDescription();
            description.SampleDescription = new SampleDescription(4, 0);
            return description;
        }

        protected override void CreateDeviceDependentResources(DeviceManager deviceManager)
        {
            base.CreateDeviceDependentResources(deviceManager);

            // Release all resources
            RemoveAndDispose(ref vertexShader);

            //RemoveAndDispose(ref depthPixelShader);
            //RemoveAndDispose(ref depthPixelShaderBytecode);
            //RemoveAndDispose(ref lambertShader);

            RemoveAndDispose(ref blinnPhongShader);

            RemoveAndDispose(ref envMapVSShader);
            RemoveAndDispose(ref envMapGSShader);
            RemoveAndDispose(ref envMapPSShader);

            RemoveAndDispose(ref vertexLayout);
            RemoveAndDispose(ref perObjectBuffer);
            RemoveAndDispose(ref perFrameBuffer);
            RemoveAndDispose(ref perMaterialBuffer);
            RemoveAndDispose(ref perArmatureBuffer);

            RemoveAndDispose(ref depthStencilState);

            RemoveAndDispose(ref rasterizerState);

            // Get a reference to the Device1 instance and immediate context
            var device = deviceManager.Direct3DDevice;
            var context = deviceManager.Direct3DContext;

            // Compile and create the vertex shader and input layout
            using (var vertexShaderBytecode = HLSLCompiler.CompileFromFile(@"Shaders\VS.hlsl", "VSMain", "vs_5_0"))
            {
                vertexShader = ToDispose(new VertexShader(device, vertexShaderBytecode));
                // Layout from VertexShader input signature
                vertexLayout = ToDispose(new InputLayout(device,
                    vertexShaderBytecode.GetPart(ShaderBytecodePart.InputSignatureBlob),
                new[]
                {
                    // "SV_Position" = vertex coordinate in object space
                    new InputElement("SV_Position", 0, Format.R32G32B32_Float, 0, 0),
                    // "NORMAL" = the vertex normal
                    new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                    // "COLOR"
                    new InputElement("COLOR", 0, Format.R8G8B8A8_UNorm, 24, 0),
                    // "UV"
                    new InputElement("TEXCOORD", 0, Format.R32G32_Float, 28, 0),
                    // "SkinIndices"
                    new InputElement("BLENDINDICES", 0, Format.R32G32B32A32_UInt, 36, 0),
                    // "SkinWeights"
                    new InputElement("BLENDWEIGHT", 0, Format.R32G32B32A32_Float, 52, 0),
                }));
            }

            // Compile and create the pixel shader
            //using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\SimplePS.hlsl", "PSMain", "ps_5_0"))
            //    pixelShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the depth vertex and pixel shaders
            // This shader is for checking what the depth buffer would look like
            //using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\DepthPS.hlsl", "PSMain", "ps_5_0"))
            //    depthPixelShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the Lambert pixel shader
            //using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\DiffusePS.hlsl", "PSMain", "ps_5_0"))
            //    lambertShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the blinn phong pixel shader
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\BlinnPhongPS.hlsl", "PSMain", "ps_5_0"))
                blinnPhongShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the Lambert pixel shader
            //using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\PhongPS.hlsl", "PSMain", "ps_5_0"))
            //    phongShader = ToDispose(new PixelShader(device, bytecode));

            // Compile CubeMap VS and GS shaders
            using (var vsBytecode = HLSLCompiler.CompileFromFile(@"Shaders\CubeMap.hlsl", "VS_CubeMap", "vs_5_0", null))
            using (var gsBytecode = HLSLCompiler.CompileFromFile(@"Shaders\CubeMap.hlsl", "GS_CubeMap", "gs_5_0", null))
            using (var psBytecode = HLSLCompiler.CompileFromFile(@"Shaders\CubeMap.hlsl", "PS_CubeMap", "ps_5_0", null))
            {
                envMapVSShader = ToDispose(new VertexShader(device, vsBytecode));
                envMapGSShader = ToDispose(new GeometryShader(device, gsBytecode));
                envMapPSShader = ToDispose(new PixelShader(device, psBytecode));
            }

            // IMPORTANT: A constant buffer's size must be a multiple of 16-bytes
            // use LayoutKind.Explicit and an explicit Size= to force this for structures
            // or alternatively add padding fields and use a LayoutKind.Sequential and Pack=1

            // Create the constant buffer that will
            // store our worldViewProjection matrix
            perObjectBuffer = ToDispose(new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf<ConstantBuffers.PerObject>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per frame constant buffer
            // lighting / camera position
            perFrameBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ConstantBuffers.PerFrame>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per material constant buffer
            perMaterialBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ConstantBuffers.PerMaterial>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per armature/skeletong constant buffer
            perArmatureBuffer = ToDispose(new Buffer(device, ConstantBuffers.PerArmature.Size(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Configure the depth buffer to discard pixels that are
            // further than the current pixel.
            depthStencilState = ToDispose(new DepthStencilState(device,
                new DepthStencilStateDescription()
                {
                    IsDepthEnabled = true, // enable depth?
                    DepthComparison = Comparison.Less,
                    DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All,
                    IsStencilEnabled = false,// enable stencil?
                    StencilReadMask = 0xff, // 0xff (no mask)
                    StencilWriteMask = 0xff,// 0xff (no mask)
                    // Configure FrontFace depth/stencil operations
                    FrontFace = new DepthStencilOperationDescription()
                    {
                        Comparison = Comparison.Always,
                        PassOperation = StencilOperation.Keep,
                        FailOperation = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment
                    },
                    // Configure BackFace depth/stencil operations
                    BackFace = new DepthStencilOperationDescription()
                    {
                        Comparison = Comparison.Always,
                        PassOperation = StencilOperation.Keep,
                        FailOperation = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement
                    },
                }));

            rasterizerState = ToDispose(new RasterizerState(this.DeviceManager.Direct3DDevice, new RasterizerStateDescription()
            {
                FillMode = FillMode.Solid,
                CullMode = CullMode.Back,
            }));

            // Initialize the ImmediateContext pipeline stages
            //InitializeContext(context, true);
        }

        VertexShader activeVertexShader = null;
        GeometryShader activeGeometryShader = null;
        PixelShader activePixelShader = null;
        protected void InitializeContext(DeviceContext context, bool updateRenderTarget)
        {
            // Tell the IA what the vertices will look like
            context.InputAssembler.InputLayout = vertexLayout;

            // Set the constant buffers for vertex shader stage
            context.VertexShader.SetConstantBuffer(0, perObjectBuffer);
            context.VertexShader.SetConstantBuffer(1, perFrameBuffer);
            context.VertexShader.SetConstantBuffer(2, perMaterialBuffer);
            context.VertexShader.SetConstantBuffer(3, perArmatureBuffer);

            // Set the default vertex shader to run
            context.VertexShader.Set(activeVertexShader);

            // Set the constant buffer for the geometry shader stage
            context.GeometryShader.SetConstantBuffer(0, perObjectBuffer);
            context.GeometryShader.SetConstantBuffer(1, perFrameBuffer);

            context.GeometryShader.Set(activeGeometryShader);

            // Set our pixel shader constant buffers
            context.PixelShader.SetConstantBuffer(1, perFrameBuffer);
            context.PixelShader.SetConstantBuffer(2, perMaterialBuffer);

            // Set the pixel shader to run
            context.PixelShader.Set(activePixelShader);

            // Set our depth stencil state
            context.OutputMerger.DepthStencilState = depthStencilState;

            // Set No culling for rasterizer
            // Note: if culling was enabled the cubemap requires
            //       frontface culling, not backface culling
            context.Rasterizer.State = rasterizerState;

            // When rendering cube maps we don't want to change the render target
            if (updateRenderTarget)
            {
                // Set viewport
                context.Rasterizer.SetViewport(this.Viewport);

                // Set render targets
                context.OutputMerger.SetTargets(this.DepthStencilView, this.RenderTargetView);
            }
        }

        // Action used to create and initialize contexts
        private void SetupContextList()
        {
            // Remove existing deferred contexts
            if (contextList != null)
            {
                foreach (var context in contextList)
                    if (!context.IsDisposed && context.TypeInfo != DeviceContextType.Immediate)
                        context.Dispose();
            }
            contextList = new DeviceContext[threadCount];

            // If only one context we will use the ImmediateContext directly
            if (threadCount == 1)
            {
                contextList[0] = this.DeviceManager.Direct3DContext;
                return;
            }

            for (var i = 0; i < threadCount; i++)
            {
                contextList[i] = ToDispose(new DeviceContext(this.DeviceManager.Direct3DDevice));
                InitializeContext(contextList[i], false);
            }
        }

        protected override void CreateSizeDependentResources(D3DApplicationBase app)
        {
            // Clear the render targets of any deferred contexts before
            // processing a resize.
            if (contextList != null)
            {
                foreach (var context in contextList)
                {
                    if (context != null && context.TypeInfo == DeviceContextType.Deferred)
                    {
                        context.OutputMerger.ResetTargets();
                        context.Dispose();
                    }
                }
            }

            base.CreateSizeDependentResources(app);

        }

        public override void Run()
        {
            #region Create renderers

            // Note: the renderers take care of creating their own
            // device resources and listen for DeviceManager.OnInitialize

            #region Initialize MeshRenderer instances

            // Create and initialize the mesh renderer
            var loadedMesh = Common.Mesh.LoadFromFile("Scene.cmo");
            List<MeshRenderer> meshes = new List<MeshRenderer>();
            meshes.AddRange((from mesh in loadedMesh
                             select ToDispose(new MeshRenderer(mesh))));

            // We will support a cubemap for each mesh that contains "reflector" in its name
            List<DynamicCubeMap> envMaps = new List<DynamicCubeMap>();

            // We will rotate any meshes that contains "rotate" in its name
            List<MeshRenderer> rotateMeshes = new List<MeshRenderer>();

            // We will generate meshRows * meshColumns of any mesh that contains "replicate" in its name
            int meshRows = 10;
            int meshColumns = 10;

            // Define an action to initialize our meshes so that we can
            // dynamically change the number of reflective surfaces and
            // replicated meshes
            Action createMeshes = () =>
            {
                // Clear context states, ensures we don't have
                // any of the resources we are going to release
                // assigned to the pipeline.
                DeviceManager.Direct3DContext.ClearState();
                if (contextList != null)
                {
                    foreach (var context in contextList)
                        context.ClearState();
                }

                // Remove meshes
                foreach (var mesh in meshes)
                    mesh.Dispose();
                meshes.Clear();

                // Remove environment maps
                foreach (var envMap in envMaps)
                    envMap.Dispose();
                envMaps.Clear();

                // Create non-replicated MeshRenderer instances
                meshes.AddRange(from mesh in loadedMesh
                                where !((mesh.Name ?? "").ToLower().Contains("replicate"))
                                 select ToDispose(new MeshRenderer(mesh)));

                #region Create replicated meshes
                // Add the same mesh multiple times, separate by the combined extent
                var replicatedMeshes = (from mesh in loadedMesh
                                        where (mesh.Name ?? "").ToLower().Contains("replicate")
                                        select mesh).ToArray();
                if (replicatedMeshes.Length > 0)
                {
                    var minExtent = (from mesh in replicatedMeshes
                                     orderby new { mesh.Extent.Min.X, mesh.Extent.Min.Z }
                                     select mesh.Extent).First();
                    var maxExtent = (from mesh in replicatedMeshes
                                     orderby new { mesh.Extent.Max.X, mesh.Extent.Max.Z } descending
                                     select mesh.Extent).First();
                    var extentDiff = (maxExtent.Max - minExtent.Min);

                    for (int x = -(meshColumns / 2); x < (meshColumns / 2); x++)
                    {
                        for (int z = -(meshRows / 2); z < (meshRows / 2); z++)
                        {
                            var meshGroup = (from mesh in replicatedMeshes
                                             where (mesh.Name ?? "").ToLower().Contains("replicate")
                                             select ToDispose(new MeshRenderer(mesh))).ToList();

                            // Reposition based on width/depth of combined extent
                            foreach (var m in meshGroup)
                            {
                                m.World.TranslationVector = new Vector3(m.Mesh.Extent.Center.X + extentDiff.X * x, m.Mesh.Extent.Min.Y, m.Mesh.Extent.Center.Z + extentDiff.Z * z);
                            }

                            meshes.AddRange(meshGroup);
                        }
                    }
                }
                #endregion

                #region Create reflective meshes
                // Create reflections where necessary and add rotation meshes
                int reflectorCount = 0;
                meshes.ForEach(m =>
                {
                    var name = (m.Mesh.Name ?? "").ToLower();
                    if (name.Contains("reflector") && reflectorCount < maxReflectors)
                    {
                        reflectorCount++;
                        var envMap = ToDispose(new DynamicCubeMap(512));
                        envMap.Reflector = m;
                        envMap.Initialize(this);
                        m.EnvironmentMap = envMap;
                        envMaps.Add(envMap);
                    }
                    if (name.Contains("rotate"))
                    {
                        rotateMeshes.Add(m);
                    }

                    m.Initialize(this);
                });
                #endregion

                // Initialize each mesh
                meshes.ForEach(m => m.Initialize(this));
            };
            createMeshes();

            // Set the first animation as the current animation and start clock
            meshes.ForEach(m =>
            {
                if (m.Mesh.Animations != null && m.Mesh.Animations.Any())
                    m.CurrentAnimation = m.Mesh.Animations.First().Value;
                m.Clock.Start();
            });

            // Create the overall mesh World matrix
            var meshWorld = Matrix.Identity;

            #endregion

            // Create an axis-grid renderer
            var axisGrid = ToDispose(new AxisGridRenderer());
            axisGrid.Initialize(this);

            // Create and initialize a Direct2D FPS text renderer
            var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16));
            fps.Initialize(this);

            // Create and initialize a general purpose Direct2D text renderer
            // This will display some instructions and the current view and rotation offsets
            var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12));
            textRenderer.Initialize(this);

            #endregion

            // Initialize the world matrix
            var worldMatrix = Matrix.Identity;

            // Set the camera position
            var cameraPosition = new Vector3(0, 1, 2);
            var cameraTarget = Vector3.Zero; // Looking at the origin 0,0,0
            var cameraUp = Vector3.UnitY; // Y+ is Up

            // Prepare matrices
            // Create the view matrix from our camera position, look target and up direction
            var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp);
            viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0);

            // Create the projection matrix
            /* FoV 60degrees = Pi/3 radians */
            // Aspect ratio (based on window size), Near clip, Far clip
            var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f);

            // Maintain the correct aspect ratio on resize
            Window.Resize += (s, e) =>
            {
                projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f);
            };

            #region Rotation and window event handlers

            // Create a rotation vector to keep track of the rotation
            // around each of the axes
            var rotation = new Vector3(0.0f, 0.0f, 0.0f);

            // We will call this action to update text
            // for the text renderer
            Action updateText = () =>
            {
                textRenderer.Text =
                    String.Format(
                    "\nPause rotation: P"
                    + "\nThreads: {0} (+/-)"
                    + "\nReflectors: {1} (Shift-Up/Down)"
                    + "\nCPU load: {2} matrix ops (Shift +/-)"
                    + "\nRotating meshes: {3} (Up/Down, Left/Right)"
                    + "\n(G) Build in GS (single pass): {4}"
                    ,
                        threadCount,
                        maxReflectors,
                        additionalCPULoad,
                        meshRows * meshColumns,
                        buildCubeMapGeometryInstancing);
            };

            Dictionary<Keys, bool> keyToggles = new Dictionary<Keys, bool>();
            keyToggles[Keys.Z] = false;
            keyToggles[Keys.F] = false;

            // Support keyboard/mouse input to rotate or move camera view
            var moveFactor = 0.02f; // how much to change on each keypress
            var shiftKey = false;
            var ctrlKey = false;
            var background = Color.White;
            Window.KeyDown += (s, e) =>
            {
                var context = DeviceManager.Direct3DContext;

                shiftKey = e.Shift;
                ctrlKey = e.Control;

                switch (e.KeyCode)
                {
                    // WASD -> pans view
                    case Keys.A:
                        viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f);
                        break;
                    case Keys.D:
                        viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f);
                        break;
                    case Keys.S:
                        if (shiftKey)
                            viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f);
                        else
                            viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2;
                        break;
                    case Keys.W:
                        if (shiftKey)
                            viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f);
                        else
                            viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2;
                        break;
                    // Up/Down and Left/Right - rotates around X / Y respectively
                    // (Mouse wheel rotates around Z)
                    //case Keys.Down:
                    //    worldMatrix *= Matrix.RotationX(moveFactor);
                    //    rotation += new Vector3(moveFactor, 0f, 0f);
                    //    break;
                    //case Keys.Up:
                    //    worldMatrix *= Matrix.RotationX(-moveFactor);
                    //    rotation -= new Vector3(moveFactor, 0f, 0f);
                    //    break;
                    //case Keys.Left:
                    //    worldMatrix *= Matrix.RotationY(moveFactor);
                    //    rotation += new Vector3(0f, moveFactor, 0f);
                    //    break;
                    //case Keys.Right:
                    //    worldMatrix *= Matrix.RotationY(-moveFactor);
                    //    rotation -= new Vector3(0f, moveFactor, 0f);
                    //    break;
                    case Keys.T:
                        fps.Show = !fps.Show;
                        textRenderer.Show = !textRenderer.Show;
                        break;
                    case Keys.B:
                        if (background == Color.White)
                        {
                            background = new Color(30, 30, 34);
                        }
                        else
                        {
                            background = Color.White;
                        }
                        break;
                    case Keys.G:
                        axisGrid.Show = !axisGrid.Show;
                        break;
                    case Keys.P:
                        // Pause or resume mesh animation
                        meshes.ForEach(m => {
                            if (m.Clock.IsRunning)
                                m.Clock.Stop();
                            else
                                m.Clock.Start();
                        });
                        break;
                    case Keys.X:
                        // To test for correct resource recreation
                        // Simulate device reset or lost.
                        System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                        DeviceManager.Initialize(DeviceManager.Dpi);
                        System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                        break;
                    //case Keys.Z:
                    //    keyToggles[Keys.Z] = !keyToggles[Keys.Z];
                    //    if (keyToggles[Keys.Z])
                    //    {
                    //        context.PixelShader.Set(depthPixelShader);
                    //    }
                    //    else
                    //    {
                    //        context.PixelShader.Set(pixelShader);
                    //    }
                    //    break;
                    case Keys.F:
                        keyToggles[Keys.F] = !keyToggles[Keys.F];
                        RasterizerStateDescription rasterDesc;
                        if (context.Rasterizer.State != null)
                            rasterDesc = context.Rasterizer.State.Description;
                        else
                            rasterDesc = new RasterizerStateDescription()
                            {
                                CullMode = CullMode.Back,
                                FillMode = FillMode.Solid
                            };
                        if (keyToggles[Keys.F])
                        {
                            rasterDesc.FillMode = FillMode.Wireframe;
                            rasterizerState = ToDispose(new RasterizerState(context.Device, rasterDesc));
                        }
                        else
                        {
                            rasterDesc.FillMode = FillMode.Solid;
                            rasterizerState = ToDispose(new RasterizerState(context.Device, rasterDesc));
                        }
                        break;
                    //case Keys.D1:
                    //    context.PixelShader.Set(pixelShader);
                    //    break;
                    //case Keys.D2:
                    //    context.PixelShader.Set(lambertShader);
                    //    break;
                    //case Keys.D3:
                    //    context.PixelShader.Set(phongShader);
                    //    break;
                    //case Keys.D4:
                    //    context.PixelShader.Set(blinnPhongShader);
                    //    break;
                    //case Keys.D5:
                    //    context.PixelShader.Set(simpleUVShader);
                    //    break;
                    //case Keys.D6:
                    //    context.PixelShader.Set(lambertUVShader);
                    //    break;
                    //case Keys.D7:
                    //    context.PixelShader.Set(phongUVShader);
                    //    break;
                    //case Keys.D8:
                    //    context.PixelShader.Set(blinnPhongUVShader);
                    //    break;
                }

                updateText();
            };
            Window.KeyUp += (s, e) =>
            {
                // Clear the shift/ctrl keys so they aren't sticky
                if (e.KeyCode == Keys.ShiftKey)
                    shiftKey = false;
                if (e.KeyCode == Keys.ControlKey)
                    ctrlKey = false;
            };
            Window.MouseWheel += (s, e) =>
            {
                if (shiftKey)
                {
                    // Zoom in/out
                    viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2);
                }
                else
                {
                    // rotate around Z-axis
                    viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor);
                    rotation += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor);
                }
                updateText();
            };

            var lastX = 0;
            var lastY = 0;

            Window.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    lastX = e.X;
                    lastY = e.Y;
                }
            };

            Window.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    var yRotate = lastX - e.X;
                    var xRotate = lastY - e.Y;
                    lastY = e.Y;
                    lastX = e.X;

                    // Mouse move changes
                    // Rotate view (i.e. camera)
                    //viewMatrix *= Matrix.RotationX(xRotate * moveFactor);
                    //viewMatrix *= Matrix.RotationY(yRotate * moveFactor);

                    // Rotate around origin
                    var backup = viewMatrix.TranslationVector;
                    viewMatrix.TranslationVector = Vector3.Zero;
                    viewMatrix *= Matrix.RotationX(-xRotate * moveFactor);
                    viewMatrix.TranslationVector = backup;
                    worldMatrix *= Matrix.RotationY(-yRotate * moveFactor);

                    updateText();
                }
            };

            // Display instructions with initial values
            updateText();

            #endregion

            var clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            // Setup the deferred contexts
            SetupContextList();

            #region Render loop

            // Whether or not to reinitialize meshes
            bool initializeMesh = false;

            // Define additional key handlers for controlling the
            // number of threads, reflectors, and replicated meshes
            #region Dynamic Cube map and threading KeyDown handlers
            Window.KeyDown += (s, e) =>
            {
                switch (e.KeyCode)
                {
                    case Keys.Up:
                        if (shiftKey)
                        {
                            maxReflectors++;
                        }
                        else
                        {
                            meshRows += 2;
                        }
                        initializeMesh = true;
                        break;
                    case Keys.Down:
                        if (shiftKey)
                        {
                            maxReflectors = Math.Max(0, maxReflectors-1);
                        }
                        else
                        {
                            meshRows = Math.Max(2, meshRows - 2);
                        }
                        initializeMesh = true;
                        break;
                    case Keys.Right:
                        meshColumns += 2;
                        initializeMesh = true;
                        break;
                    case Keys.Left:
                        meshColumns = Math.Max(2, meshColumns - 2);
                        initializeMesh = true;
                        break;
                    case Keys.Add:
                        if (shiftKey)
                        {
                            additionalCPULoad += 100;
                        }
                        else
                        {
                            threadCount++;
                        }
                        break;
                    case Keys.Subtract:
                        if (shiftKey)
                        {
                            additionalCPULoad = Math.Max(0, additionalCPULoad - 100);
                        }
                        else
                        {
                            threadCount = Math.Max(1, threadCount - 1);
                        }
                        break;
                    case Keys.G:
                        buildCubeMapGeometryInstancing = !buildCubeMapGeometryInstancing;
                        break;
                    default:
                        break;
                }
                updateText();
            };
            #endregion

            #region Render mesh group
            // Action for rendering a group of meshes for a
            // context (based on number of available contexts)
            Action<int, DeviceContext, Matrix, Matrix> renderMeshGroup = (contextIndex, renderContext, view, projection) =>
            {
                var viewProjection = view * projection;

                // Determine the meshes to render for this context
                int batchSize = (int)Math.Floor((double)meshes.Count / contextList.Length);
                int startIndex = batchSize * contextIndex;
                int endIndex = Math.Min(startIndex + batchSize, meshes.Count - 1);
                // If this is the last context include whatever remains to be
                // rendered due to the rounding above.
                if (contextIndex == contextList.Length - 1)
                    endIndex = meshes.Count - 1;

                // Loop over the meshes for this context and render them
                var perObject = new ConstantBuffers.PerObject();
                for (var i = startIndex; i <= endIndex; i++)
                {
                    // Simulate additional CPU load
                    for (var j = 0; j < additionalCPULoad; j++)
                    {
                        viewProjection = Matrix.Multiply(view, projection);
                    }

                    // Retrieve current mesh
                    var m = meshes[i];

                    // Check if this is a rotating mesh
                    if (rotateMeshes.Contains(m))
                    {
                        var rotate = Matrix.RotationAxis(Vector3.UnitY, m.Clock.ElapsedMilliseconds / 1000.0f);
                        perObject.World = m.World * rotate * worldMatrix;
                    }
                    else
                    {
                        perObject.World = m.World * worldMatrix;
                    }

                    // Update perObject constant buffer
                    perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                    perObject.WorldViewProjection = perObject.World * viewProjection;
                    perObject.Transpose();
                    renderContext.UpdateSubresource(ref perObject, perObjectBuffer);

                    // Provide the material and armature constant buffer to the mesh renderer
                    m.PerArmatureBuffer = perArmatureBuffer;
                    m.PerMaterialBuffer = perMaterialBuffer;

                    // Render the mesh using the provided DeviceContext
                    m.Render(renderContext);
                }
            };

            #endregion

            #region Render scene

            // Action for rendering the entire scene
            Action<DeviceContext, Matrix, Matrix, RenderTargetView, DepthStencilView, DynamicCubeMap> renderScene = (context, view, projection, rtv, dsv, envMap) =>
            {
                // We must initialize the context every time we render
                // the scene as we are changing the state depending on
                // whether we are rendering the envmaps or final scene
                InitializeContext(context, false);

                // We always need the immediate context
                // Note: the passed in context will normally be the immediate context
                // however it is possible to run this method threaded also.
                var immediateContext = this.DeviceManager.Direct3DDevice.ImmediateContext;

                // Clear depth stencil view
                context.ClearDepthStencilView(dsv, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
                // Clear render target view
                context.ClearRenderTargetView(rtv, background);

                // Create viewProjection matrix
                var viewProjection = Matrix.Multiply(view, projection);

                // Extract camera position from view
                var camPosition = Matrix.Transpose(Matrix.Invert(view)).Column4;
                cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z);

                // Setup the per frame constant buffer
                var perFrame = new ConstantBuffers.PerFrame();
                perFrame.Light.Color = new Color(0.9f, 0.9f, 0.9f, 1.0f);
                var lightDir = Vector3.Transform(new Vector3(-1f, -1f, -1f), worldMatrix);
                perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z);
                perFrame.CameraPosition = cameraPosition;
                context.UpdateSubresource(ref perFrame, perFrameBuffer);

                // Render each object

                // Prepare the default per material constant buffer
                var perMaterial = new ConstantBuffers.PerMaterial();
                perMaterial.Ambient = new Color4(0.2f);
                perMaterial.Diffuse = Color.White;
                perMaterial.Emissive = new Color4(0);
                perMaterial.Specular = Color.White;
                perMaterial.SpecularPower = 20f;
                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);

                // ----------Render meshes------------

                if (contextList.Length == 1)
                {
                    // If there is only one context available there is no need to
                    // generate command lists and execute them so just render the
                    // mesh directly on the current context (which may or may
                    // not be an immediate context depending on the caller).
                    renderMeshGroup(0, context, view, projection);
                }
                else
                {
                    // There are multiple contexts therefore
                    // we are using deferred contexts. Prepare a
                    // separate thread for each available context
                    // and render a group of meshes on each.
                    Task[] renderTasks = new Task[contextList.Length];
                    CommandList[] commands = new CommandList[contextList.Length];
                    var viewports = context.Rasterizer.GetViewports();

                    for (var i = 0; i < contextList.Length; i++)
                    {
                        // Must store the iteration value in another variable
                        // or each task action will use the last iteration value.
                        var contextIndex = i;

                        // Create task to run on new thread from ThreadPool
                        renderTasks[i] = Task.Run(() =>
                        {
                            // Retrieve context for this thread
                            var renderContext = contextList[contextIndex];
                            // Initialize the context state
                            InitializeContext(renderContext, false);

                            // Set the render targets and viewport
                            renderContext.OutputMerger.SetRenderTargets(dsv, rtv);
                            renderContext.Rasterizer.SetViewports(viewports);

                            // If we are rendering for a cubemap we must set the
                            // per environment map buffer.
                            if (envMap != null)
                                renderContext.GeometryShader.SetConstantBuffer(4, envMap.PerEnvMapBuffer);

                            // Render logic
                            renderMeshGroup(contextIndex, renderContext, view, projection);

                            // Create the command list
                            if (renderContext.TypeInfo == DeviceContextType.Deferred)
                                commands[contextIndex] = renderContext.FinishCommandList(false);
                        });
                    }
                    // Wait for all the tasks to complete
                    Task.WaitAll(renderTasks);

                    // Replay the command lists on the immediate context
                    for (var i = 0; i < contextList.Length; i++)
                    {
                        if (contextList[i].TypeInfo == DeviceContextType.Deferred && commands[i] != null)
                        {
                            immediateContext.ExecuteCommandList(commands[i], false);
                            // Clean up command list
                            commands[i].Dispose();
                            commands[i] = null;
                        }
                    }
                }
            };

            #endregion

            long frameCount = 0;
            int lastThreadCount = threadCount;

            // Create and run the render loop
            RenderLoop.Run(Window, () =>
            {
                // Allow dynamic changes to number of reflectors and replications
                if (initializeMesh)
                {
                    initializeMesh = false;
                    createMeshes();
                }

                // Allow dynamic chnages to the number of threads to use
                if (lastThreadCount != threadCount)
                {
                    SetupContextList();
                    lastThreadCount = threadCount;
                }

                // Start of frame:
                frameCount++;

                // Retrieve immediate context
                var context = DeviceManager.Direct3DContext;

                //if (frameCount % 3 == 1) // to update cubemap once every third frame
                //{
                #region Update environment maps

                // Update each of the cubemaps
                if (buildCubeMapGeometryInstancing)
                {
                    activeVertexShader = envMapVSShader;
                    activeGeometryShader = envMapGSShader;
                    activePixelShader = envMapPSShader;
                }
                else
                {
                    activeVertexShader = vertexShader;
                    activeGeometryShader = null;
                    activePixelShader = blinnPhongShader;
                }

                // Render the scene from the perspective of each of the environment maps
                foreach (var envMap in envMaps)
                {
                    var mesh = envMap.Reflector as MeshRenderer;
                    if (mesh != null)
                    {
                        // Calculate view point for reflector
                        var meshCenter = Vector3.Transform(mesh.Mesh.Extent.Center, mesh.World * worldMatrix);
                        envMap.SetViewPoint(new Vector3(meshCenter.X, meshCenter.Y, meshCenter.Z));
                        if (buildCubeMapGeometryInstancing)
                        {
                            // Render cubemap in single full render pass using
                            // geometry shader instancing.
                            envMap.UpdateSinglePass(context, renderScene);
                        }
                        else
                        {
                            // Render cubemap in 6 full render passes
                            envMap.Update(context, renderScene);
                        }
                    }
                }

                #endregion
                //}

                #region Render final scene
                // Reset the vertex, geometry and pixel shader
                activeVertexShader = vertexShader;
                activeGeometryShader = null;
                activePixelShader = blinnPhongShader;
                // Initialize context (also resetting the render targets)
                InitializeContext(context, true);

                // Render the final scene
                renderScene(context, viewMatrix, projectionMatrix, RenderTargetView, DepthStencilView, null);
                #endregion

                // Render FPS
                fps.Render();

                // Render instructions + position changes
                textRenderer.Render();

                // Present the frame
                Present();
            });
            #endregion
        }
    }
}

redpajama_set_name: RedPajamaGithub


Fantastic, Rae - as Janet says - where on earth do you find the time to do this??????
Ah, the Cardiff rift - what's it like????
Plenty of leisure time there then?
all the extra dimension as a pain in the bum to dust.
See, I was thinking that perhaps I ought to have an etsy shop. I really would like to sell my bags, etc, but the clientele just isn't right here. Maybe an etsy shop is the answer?
Yay 1+1 = haven't had that for a g e s !
I've not done anything with it since before Christmas. it was dead easy. getting really top drawer pics is the key.
I need a decent camera then, perhaps.
or a friend with a decent camera, who you can buy off with cake.
Just caught up with this - well done Rae! I'm sure you'll have a very proud aunt.
- etsy used to be the best site, but lately Folksy has improved by leaps and bounds and is way simpler to set up and use (and is all in £ and p not $ ).Many more people look at the stuff in my folksy shop than my etsy shop.Etsy is still biggest in the USA, folksy is a UK site and increasingly folksy is where uk customers go to browse for 'stuff'.
You need a reasonable camera that can handle close-ups, doesn't need to be wildly good- my 99p on ebay camera does me proud- the lighting is the important thing, just make sure the light is bright enough to show everything.
Kate, I have spent about an hour looking through the bags for sale on Folksy, and I reckon maybe I could join up to that site. I'll have to think about how to organise it - as I don't have a Paypal a/c - yet!!


text:
Off To Work Event Photography Awards 2020 Winners Unveiled!
Posted by Terry Hope | 18 Nov, 2020 | Architecture, Awards, News, Portraits, Wildlife, Competitions, Sports, Black and White, Food and Drink
This year's Overall Winner of the prestigious Off To Work Event Photography Awards is photographer Deb Porter, for her well observed portrait of catering icon Albert Roux OBE. The then 84-year old chef was pictured assiduously checking plates before they were delivered to diners at Keith Prowse's 700-seater restaurant The Lawn during last year's Wimbledon Tennis Championships.
Deb's winning photo also won the Catering category, and judges, who included Professional Photo's editor Terry Hope, hailed it as a shining example of the commitment and attention to detail necessary to succeed in the sector.
Now in its seventh year, the EPAs were founded by Philip Atkins, managing director of event staffing agency, Off To Work. The 2020 competition not only attracted a record number of entries, but also a record number of judges, through an online platform that was launched during lockdown that registered thousands of public votes, leading to an additional set of People's Choice Awards.
Last year's overall winner, Andrew Billington, claimed this year's runners-up prize with his beguiling Wedding Category winner 'Peek-a-boo!', and there were highly-commended awards for Dutch photographer, Floris Heuer, who caught 'Santa on a Break' during a corporate Christmas party; and James Bridle, whose 'Rockstar' is American rapper, Post Malone, firing up the crowd from the main stage at the Reading Festival.
The overall winner of the special People's Choice Award was also an impressive flame-filled moment at a music event, Fire at Creamfields by Jack Kimber, while the Portfolio Award was won by Laura De Meo for her collection entered into the new Fashion Events category.
Other notable award winners were Noah Goodrich, who was a double category winner, Ian Knight, who again won the Best Amateur award, and Jesus Figueirido Estevez, who won the new Visit Britain sponsored Best of British category with a shot inside the London Coliseum, grandly set up for the Evening Standard Theatre Awards.
www.eventphotographyawards.com
See the winners photos in the gallery below.
The photo contest is over
You have already voted for this file
You have already used all your votes
No files found
Photo contest ist over
Name 100
😀😃😄😁😆😅😂🤣🙂🙃😊😇😍😘😜🤑🤗🤔😔🤢🤯🧐🥳🙆🖖👌🤏✌👍👎👊👏🤝🚀🛸🌙⭐⚡🔥❄🌍🌎🌏🏔🌋🏖🏝🍊🍄🍿🍣🍰🍕🍔🍟🛀💎🗺⏰🕹📚🐱🐪🐹🐤
Photo by: Floris Heuer - contact before use
Photography by: Jack Kimber Photography (www.facebook.com/jackkimberphotography)
photographer-budapest-corporate-company-portrait-hungary
alistair veryard photography event photography awards entry
PreviousWinner – Alison Fairley – Picture of the Week
NextSINWP Bird Photographer of the Year 2020 in aid of RSPB – Winner Announced
Terry Hope
Owner of So Smart Media and publisher and owner of Professional Photo Magazine. Freelance writing and photography, working for publications such as The Times, The Sunday Times, The Sunday Telegraph Magazine, The Guardian Weekend Magazine, The Evening Standard and The Independent.
The Panasonic Lumix S1 Shoot with Rachel Thornhill
Time to Turn Pro part 20 – To Blog or not to Blog?
Video: Andy Rouse's Top Five Images with the Olympus OMD E-M1X

redpajama_set_name: RedPajamaCommonCrawl


A piece of malicious code is making the rounds of the Internet masquerading as a Tsunami relief donation request. While not really surprising I find this is somewhat of a new low even for the writers of malware. Words like despicable, shameful, contemptible, pathetic, and feeble come to mind. I had to check a thesaurus for printable comments, can you tell? Filter attachments at your perimeter in organizations, use up-to-date anti-virus, and as users do not open attachments.
Oracle has released a critical patch update to address vulnerabilities in the RDBMS products. The full details of the vulnerabilities have not yet been released. Oracle has rated some of them as having wide impact. NGSSoftware, who have released an advisory, rates many of them as high risk. They include privilege escalation and a buffer overflow condition.
Upswings in scanning activity for ports tcp/901 un-explained, possibly looking for swat/samba installs? Share your theories and packet captures.


Changsha Decarnon Electronics Co., LTD. is a comprehensive battery manufacturer which specialized in the research and development, production and sale of all kinds of button cell battery. The main products are: 1.4V zinc air battery (Hearing Aid Battery), 1.55V AG alkaline button cell, SR silver oxide battery, 3V CR lithium manganese button cell, 3.6 V LIR lithium ion battery and button cell battery holders. At the same time, we can provide high quality OEM and battery welding feet processing services according to customers specific needs.
Decarnon was established in 2000. Through more than ten years development and accumulation, it has formed a professional service system of button cell batteries and peripheral accessories of button cell as the core. Its products are widely used in computer motherboard, storage card, music card, calculator, electronic watches, electronic scales, tiny radio instrument and apparatus, medical equipment, LED lamp, automobile pressure gauge, thin remote controls, control board, etc. Due to high quality products and professional service, our products not only best-sell in domestic market, but also export to Europe and America, southeast Asia and other countries and regions and well received by the customers.
In order to further meet customer needs, more professional customer service team and provide more perfect service, Decarnon electronic set up specialized battery sale division in Changsha high and new technology development zone. We will adhere to the idea of "profession lead future" , as always with demand orientation, research and development as the driving force, taking the quality as the core, continue to customize more high-quality battery solutions for you.


> > >       menu file for the same application.
> > That's good idea in general.  I hope lintian warning should come soon.
> In general: Do not use NotShowIn/OnlyShowIn for most applications.
> exclusively configuration tools specific to one desktop environment.
they did show on KDE's menus or not.
hides potential issues when abused, so it might not be a good idea.


text:
import { Octokit } from '@octokit/core'

export default new Octokit()


List of Camborne based lawyers & solicitors specialising in personal injury, family, employment & business law.
QualitySolicitors Nalders are one of the UK's leading Solicitors firms. We are the UK's first legal brand and have a strong reputation for being the best Solicitors in Camborne. QualitySolicitors Nalders are one of the UK's leading Solicitors firms. We are the UK's first legal brand and have a strong reputation for being the best Solicitors in Camborne.


Yesterday, Little Man and I were watching TV.
A commercial for Build-A-Bear Workshop came on. Yes, it's a cute idea. Yes, I think there's one at Navy Pier. No, we've never been.
Little Man said: "Mommy, can we go there and build a fuzzy sheep?"
I said: (Kind of half a$$ because I think these places are really expensive, and I'd like to put it off because I never spend money...) "That's a mall store. Next time we go see Grandma Susan we can go. There's a mall near her. I'm sure they'll have one in her mall."
He said: "OK Mommy...What's a mall?"
Is a good thing, or a bad thing that my 4 year old doesn't know what a mall is???
Only if his peers make fun of him.
I get this one. There's a mall by Grandmas, and hey while we at it there is the good possiblity grandma will get suckerred in to buying the kiddos some little critters.
Okay, I'm in for that.
Hmmmm....unless, I can convince the kiddos they would rather take a mini horse home instead.
It is SUCH a GOOD THING !!
I definitely think it is a good thing.


The icy relationship between the United States and Cuba is officially thawing, with a recent meeting of the countries' leaders.. the first time that's happened in over 50 years. Ties between the US and Cuba were severed in 1961 when the US tried to overthrow Fidel Castro's government...triggering the Cuban Missile crisis and a decades long stand-off over trade and diplomacy. So what is driving this rapprochment and what might the economic and political benefits be for both countries? Journalist and author Anne Louise Bardach, has written numerous books about Cuba, including 2009's "Without Fidel - a Death Foretold in Miami, Havana and Washington. She's interviewed Fidel Castro, his brother Raul as well as ordinary Cubans, dissidents and politicos.


text:
The 2017 Kentucky Christian Knights football team represented Kentucky Christian University in the 2017 NAIA football season. The Knights played their home games at KCU Field, in Grayson, Kentucky. Kentucky Christian competed in the Bluegrass Division of the Mid-South Conference. The team was led by first-year head coach Corey Fipps and finished 1–10 overall, 1–5 in conference play to finish sixth in the Bluegrass Division.

Schedule

References

Kentucky Christian
Kentucky Christian Knights football seasons
Kentucky Christian Knights football

redpajama_set_name: RedPajamaWikipedia


text:
'Tolkien': New Trailer For Movie About 'The Hobbit' and 'Lord Of The Rings' Author J.R.R. Tolkien Released
Last month we saw an "official trailer" for Tolkien, a J.R.R. Tolkien biopic. But that trailer was much more of a teaser at less than a minute long. Now Fox Searchlight has released a proper official trailer, which runs over two minutes long.
The movie stars Nicholas Hoult as the The Hobbit and The Lord of the Rings author, and he's joined on the cast by Lily Collins, Colm Meaney, Anthony Boyle, Patrick Gibson, Tom Glynn-Carney, Craig Roberts, Laura Donnelly, Genevieve O'Reilly, Pam Ferris, and Derek Jacobi.
Continue below for a synopsis for Tolkien, and to check out the new trailer for the movie.
Topics: Movies, News, Trailers
Tags: Anthony Boyle, Colm Meaney, Craig Roberts, David Gleeson, Derek Jacobi, Dome Karukoski, Genevieve O'Reilly, J.R.R. Tolkien, Laura Donnelly, Lily Collins, Nicholas Hoult, Pam Ferris, Patrick Gibson, Stephen Beresford, Tolkien, Tom Glynn-Carney
Trailer For 'Tolkien' Starring Nicholas Hoult As 'Lord Of The Rings' Author J.R.R. Tolkien Released
By The Movie God | @ | February 14th, 2019 at 12:00 pm
Fox Searchlight has released an official trailer for Tolkien, a movie about The Hobbit and The Lord of the Rings author J.R.R. Tolkien and some of the events in his life which helped inspire his works.
While dubbed an "official trailer," this one is definitely closer to a teaser trailer or even a TV spot at well under a minute in length. But with Shazam! releasing a teaser trailer that was almost three minutes long, I honestly have no idea what the hell is going on anymore and I just try to enjoy whatever is shared with us.
You can find more on Tolkien including a brief synopsis, and check out the trailer below.
Topics: Movies, News