* Adjustment: Initial CMake reworking.

This commit is contained in:
Robert MacGregor 2022-05-13 23:42:41 -04:00
parent 516163fd5d
commit d7cdf54661
5394 changed files with 2615532 additions and 8711 deletions

View file

@ -0,0 +1,62 @@
ASSIMP SAMPLES README
=====================
1. General
----------
This directory contains various samples to illustrate Assimp's
use in various real-world environments. Workspaces to build the
samples can be found in the respective directories. The VC workspaces
copy the created executables to the ./bin directory.
All GL-based samples depend on FreeGLUT, the image loading will be done
by a header-only library. For convenience, these libraries are included
in the repository in their respective Windows/x86 prebuilt versions.
To build on linux, install freeglut using the package manager of your
choice. For instance on Ubuntu to install freeglut you can use the following
command:
> sudo apt install freeglut
All samples will be placed at
Win32: <assimp_repo>/<config>/bin
or Linux : <assimp_repo>/bin
2. List of samples
------------------
SimpleOpenGL
A very simple and straightforward OpenGL sample. It loads a
model (gets the path to it on the command line, default is dwarf.x)
and displays the model as wireframe. Animations and materials are
not evaluated at all. This samples uses the C interface to Assimp.
Basic materials are displayed, but no textures.
This sample should work virtually everywhere, provided glut
is available.
SimpleTexturedOpenGL
An extended OpenGL sample, featuring texturing using the DevIL
library. Based on SimpleOpenGL and the NeHe GL tutorial style.
This is a Windows-only sample.
This sample was kindly provided by SamHayne (http://sf.net/users/samhayne/)
See http://sourceforge.net/projects/assimp/forums/forum/817654/topic/3736373
SimpleAssimpViewX
A Mac OSX-based viewer app. This sample was kindly provided by drparallax.
See http://sourceforge.net/projects/assimp/forums/forum/817654/topic/3917829

View file

@ -0,0 +1,52 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UTFConverter.h"
namespace AssimpSamples {
namespace SharedCode {
typename UTFConverter::UTFConverterImpl UTFConverter::impl_;
}
}

View file

@ -0,0 +1,92 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
#define ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
#include <string>
#include <locale>
#include <codecvt>
namespace AssimpSamples {
namespace SharedCode {
// Used to convert between multibyte and unicode strings.
class UTFConverter {
using UTFConverterImpl = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
public:
UTFConverter(const char* s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const wchar_t* s) :
s_(impl_.to_bytes(s)),
ws_(s) {
}
UTFConverter(const std::string& s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const std::wstring& s) :
s_(impl_.to_bytes(s)),
ws_(s) {
}
inline const char* c_str() const {
return s_.c_str();
}
inline const std::string& str() const {
return s_;
}
inline const wchar_t* c_wstr() const {
return ws_.c_str();
}
private:
static UTFConverterImpl impl_;
std::string s_;
std::wstring ws_;
};
}
}
#endif // ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H

View file

@ -0,0 +1,29 @@
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw9840\paperh8400
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\b\fs24 \cf0 Engineering:
\b0 \
Some people\
\
\b Human Interface Design:
\b0 \
Some other people\
\
\b Testing:
\b0 \
Hopefully not nobody\
\
\b Documentation:
\b0 \
Whoever\
\
\b With special thanks to:
\b0 \
Mom\
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,923 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1060</int>
<string key="IBDocument.SystemVersion">10F569</string>
<string key="IBDocument.InterfaceBuilderVersion">788</string>
<string key="IBDocument.AppKitVersion">1038.29</string>
<string key="IBDocument.HIToolboxVersion">461.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">788</string>
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="5"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="999730711">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomObject" id="488872867">
<string key="NSClassName">MyDocument</string>
</object>
<object class="NSCustomObject" id="416682482">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1056315952">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSWindowTemplate" id="827802848">
<int key="NSWindowStyleMask">15</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{78, 334}, {466, 466}}</string>
<int key="NSWTFlags">1081606144</int>
<string key="NSWindowTitle">Window</string>
<string key="NSWindowClass">NSWindow</string>
<string key="NSViewClass">View</string>
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<string key="NSWindowContentMinSize">{131.131, 86}</string>
<object class="NSView" key="NSWindowView" id="317955023">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTextField" id="36964479">
<reference key="NSNextResponder" ref="317955023"/>
<int key="NSvFlags">256</int>
<string key="NSFrame">{{98, 222}, {269, 22}}</string>
<reference key="NSSuperview" ref="317955023"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="462040940">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">138412032</int>
<string key="NSContents">Your document contents here</string>
<object class="NSFont" key="NSSupport">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">18</double>
<int key="NSfFlags">16</int>
</object>
<reference key="NSControlView" ref="36964479"/>
<object class="NSColor" key="NSBackgroundColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
</object>
<object class="NSColor" key="NSTextColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">controlTextColor</string>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
</object>
</object>
</object>
<object class="NSCustomView" id="644409269">
<reference key="NSNextResponder" ref="317955023"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{466, 466}</string>
<reference key="NSSuperview" ref="317955023"/>
<string key="NSClassName">NSView</string>
</object>
</object>
<string key="NSFrameSize">{466, 466}</string>
<reference key="NSSuperview"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1280, 832}}</string>
<string key="NSMinSize">{131.131, 108}</string>
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="827802848"/>
<reference key="destination" ref="488872867"/>
</object>
<int key="connectionID">17</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="488872867"/>
<reference key="destination" ref="827802848"/>
</object>
<int key="connectionID">18</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">_view</string>
<reference key="source" ref="488872867"/>
<reference key="destination" ref="644409269"/>
</object>
<int key="connectionID">100022</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<reference key="object" ref="0"/>
<reference key="children" ref="999730711"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="488872867"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="416682482"/>
<reference key="parent" ref="0"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="827802848"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="317955023"/>
</object>
<reference key="parent" ref="0"/>
<string key="objectName">Window</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="317955023"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="36964479"/>
<reference ref="644409269"/>
</object>
<reference key="parent" ref="827802848"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">20</int>
<reference key="object" ref="36964479"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="462040940"/>
</object>
<reference key="parent" ref="317955023"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">100020</int>
<reference key="object" ref="462040940"/>
<reference key="parent" ref="36964479"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1056315952"/>
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">100021</int>
<reference key="object" ref="644409269"/>
<reference key="parent" ref="317955023"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-3.IBPluginDependency</string>
<string>100020.IBPluginDependency</string>
<string>100021.IBPluginDependency</string>
<string>20.IBPluginDependency</string>
<string>20.ImportedFromIB2</string>
<string>5.IBEditorWindowLastContentRect</string>
<string>5.IBPluginDependency</string>
<string>5.IBWindowTemplateEditedContentRect</string>
<string>5.ImportedFromIB2</string>
<string>5.windowTemplate.hasMinSize</string>
<string>5.windowTemplate.minSize</string>
<string>6.IBPluginDependency</string>
<string>6.ImportedFromIB2</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
<string>{{424, 525}, {466, 466}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{424, 525}, {466, 466}}</string>
<integer value="1"/>
<integer value="1"/>
<string>{131.131, 86}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1"/>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">100022</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">FirstResponder</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBUserSource</string>
<string key="minorKey"/>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MyDocument</string>
<string key="superclassName">NSPersistentDocument</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">_view</string>
<string key="NS.object.0">NSView</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">_view</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">_view</string>
<string key="candidateClassName">NSView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">MyDocument.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MyDocument</string>
<string key="superclassName">NSPersistentDocument</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBUserSource</string>
<string key="minorKey"/>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSPersistentDocument</string>
<string key="superclassName">NSDocument</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBUserSource</string>
<string key="minorKey"/>
</object>
</object>
</object>
<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">NSActionCell</string>
<string key="superclassName">NSCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSActionCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<string key="superclassName">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="877220377">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSApplication.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="236754727">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSApplicationScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="530996899">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSColorPanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSHelpManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSPageLayout.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSApplication</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSUserInterfaceItemSearching.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSCell</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSControl</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="440999483">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSControl.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSDocument</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="actions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>printDocument:</string>
<string>revertDocumentToSaved:</string>
<string>runPageLayout:</string>
<string>saveDocument:</string>
<string>saveDocumentAs:</string>
<string>saveDocumentTo:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>printDocument:</string>
<string>revertDocumentToSaved:</string>
<string>runPageLayout:</string>
<string>saveDocument:</string>
<string>saveDocumentAs:</string>
<string>saveDocumentTo:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBActionInfo">
<string key="name">printDocument:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">revertDocumentToSaved:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">runPageLayout:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">saveDocument:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">saveDocumentAs:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">saveDocumentTo:</string>
<string key="candidateClassName">id</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDocument.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSDocument</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDocumentScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSFormatter</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSFormatter.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSMenu</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="779771453">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSMenu.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSAccessibility.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="877220377"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="236754727"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="530996899"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="440999483"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDictionaryController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDragging.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSFontManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSFontPanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSKeyValueBinding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<reference key="sourceIdentifier" ref="779771453"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSNibLoading.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSOutlineView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSPasteboard.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSSavePanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTableView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSToolbarItem.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="930720818">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSArchiver.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSClassDescription.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSObjectScripting.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSPortCoder.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptClassDescription.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptKeyValueCoding.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptObjectSpecifiers.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSScriptWhoseTests.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/IKImageBrowserView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/IKSaveOptions.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">ImageKit.framework/Headers/ImageKitDeprecated.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">PDFKit.framework/Headers/PDFDocument.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">PDFKit.framework/Headers/PDFView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QTKit.framework/Headers/QTCaptureDecompressedAudioOutput.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QTKit.framework/Headers/QTCaptureDecompressedVideoOutput.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QTKit.framework/Headers/QTCaptureFileOutput.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QTKit.framework/Headers/QTCaptureVideoPreviewOutput.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QTKit.framework/Headers/QTCaptureView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QTKit.framework/Headers/QTMovie.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QTKit.framework/Headers/QTMovieView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzComposer.framework/Headers/QCCompositionParameterView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzComposer.framework/Headers/QCCompositionPickerView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuartzFilters.framework/Headers/QuartzFilterManager.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QuickLookUI.framework/Headers/QLPreviewPanel.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSPersistentDocument</string>
<string key="superclassName">NSDocument</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSPersistentDocument.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSInterfaceStyle.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSResponder</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSResponder.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSTextField</string>
<string key="superclassName">NSControl</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTextField.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSTextFieldCell</string>
<string key="superclassName">NSActionCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSTextFieldCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSClipView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSMenuItem.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSRulerView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSView</string>
<string key="superclassName">NSResponder</string>
<reference key="sourceIdentifier" ref="930720818"/>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSDrawer.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<string key="superclassName">NSResponder</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindow.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1060" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<string key="IBDocument.LastKnownRelativeProjectPath">../SimpleAssimpViewX.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>

View file

@ -0,0 +1,98 @@
//
// v002MeshHelper.h
// v002 Model Importer
//
// Created by vade on 9/26/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <OpenGL/OpenGL.h>
#import "color4.h"
#import "vector3.h"
#import "vector2.h"
#import "matrix4x4.h"
/* workflow:
1) create a new scene wrapper
2) populate an array of of meshHelpers for each mesh in the original scene
3) (eventually) create an animator instance
4) scale the asset (needed?)
5) create the asset data (GL resources, textures etc)
5a) for each mesh create a material instance
5b) create a static vertex buffer
5c) create index buffer
5d) populate the index buffer
5e) (eventually) gather weights
*/
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
struct Vertex
{
aiVector3D vPosition;
aiVector3D vNormal;
aiColor4D dColorDiffuse;
aiVector3D vTangent;
aiVector3D vBitangent;
aiVector3D vTextureUV;
aiVector3D vTextureUV2;
unsigned char mBoneIndices[4];
unsigned char mBoneWeights[4]; // last Weight not used, calculated inside the vertex shader
};
// Helper Class to store GPU related resources from a given aiMesh
// Modeled after AssimpView asset helper
@interface MeshHelper : NSObject
{
// Display list ID, this one shots *all drawing* of the mesh. Only ever use this to draw. Booya.
GLuint displayList;
// VAO that encapsulates all VBO drawing state
GLuint vao;
// VBOs
GLuint vertexBuffer;
GLuint indexBuffer;
GLuint normalBuffer;
GLuint numIndices;
// texture
GLuint textureID;
// Material
aiColor4D diffuseColor;
aiColor4D specularColor;
aiColor4D ambientColor;
aiColor4D emissiveColor;
GLfloat opacity;
GLfloat shininess;
GLfloat specularStrength;
BOOL twoSided;
}
@property (readwrite, assign) GLuint vao;
@property (readwrite, assign) GLuint displayList;
@property (readwrite, assign) GLuint vertexBuffer;
@property (readwrite, assign) GLuint indexBuffer;
@property (readwrite, assign) GLuint normalBuffer;
@property (readwrite, assign) GLuint numIndices;
@property (readwrite, assign) GLuint textureID;
@property (readwrite, assign) aiColor4D* diffuseColor;
@property (readwrite, assign) aiColor4D* specularColor;
@property (readwrite, assign) aiColor4D* ambientColor;
@property (readwrite, assign) aiColor4D* emissiveColor;
@property (readwrite, assign) GLfloat opacity;
@property (readwrite, assign) GLfloat shininess;
@property (readwrite, assign) GLfloat specularStrength;
@property (readwrite, assign) BOOL twoSided;
@end

View file

@ -0,0 +1,99 @@
//
// v002MeshHelper.m
// v002 Model Importer
//
// Created by vade on 9/26/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "ModelLoaderHelperClasses.h"
@implementation MeshHelper
@synthesize vao;
@synthesize displayList;
@synthesize vertexBuffer;
@synthesize indexBuffer;
@synthesize normalBuffer;
@synthesize numIndices;
@synthesize textureID;
@dynamic diffuseColor;
@dynamic specularColor;
@dynamic ambientColor;
@dynamic emissiveColor;
@synthesize opacity;
@synthesize shininess;
@synthesize specularStrength;
@synthesize twoSided;
- (id) init
{
if((self = [super init]))
{
diffuseColor = aiColor4D(0.8, 0.8, 0.8, 1.0);
specularColor = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f);
ambientColor = aiColor4D(0.2f, 0.2f, 0.2f, 1.0f);
emissiveColor = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f);
}
return self;
}
- (void) setDiffuseColor:(aiColor4D*) color;
{
diffuseColor.r = color->r;
diffuseColor.g = color->g;
diffuseColor.b = color->b;
diffuseColor.a = color->a;
}
- (aiColor4D*) diffuseColor
{
return &diffuseColor;
}
- (void) setSpecularColor:(aiColor4D*) color;
{
specularColor.r = color->r;
specularColor.g = color->g;
specularColor.b = color->b;
specularColor.a = color->a;
}
- (aiColor4D*) specularColor
{
return &specularColor;
}
- (void) setAmbientColor:(aiColor4D*) color;
{
ambientColor.r = color->r;
ambientColor.g = color->g;
ambientColor.b = color->b;
ambientColor.a = color->a;
}
- (aiColor4D*) ambientColor
{
return &ambientColor;
}
- (void) setEmissiveColor:(aiColor4D*) color;
{
emissiveColor.r = color->r;
emissiveColor.g = color->g;
emissiveColor.b = color->b;
emissiveColor.a = color->a;
}
- (aiColor4D*) emissiveColor
{
return &emissiveColor;
}
@end

View file

@ -0,0 +1,60 @@
//
// MyDocument.h
// DisplayLinkAsyncMoviePlayer
//
// Created by vade on 10/26/10.
// Copyright __MyCompanyName__ 2010 . All rights reserved.
//
#import "ModelLoaderHelperClasses.h"
// assimp include files. These three are usually needed.
#import "cimport.h"
#import "postprocess.h"
#import "scene.h"
#import "types.h"
#import <Cocoa/Cocoa.h>
#import <OpenGL/OpenGL.h>
#import <Quartz/Quartz.h>
@interface MyDocument : NSPersistentDocument
{
CVDisplayLinkRef _displayLink;
NSOpenGLContext* _glContext;
NSOpenGLPixelFormat* _glPixelFormat;
NSView* _view;
// Assimp Stuff
aiScene* _scene;
aiVector3D scene_min, scene_max, scene_center;
double normalizedScale;
// Our array of textures.
GLuint *textureIds;
// only used if we use
NSMutableArray* modelMeshes;
BOOL builtBuffers;
NSMutableDictionary* textureDictionary; // Array of Dictionaries that map image filenames to textureIds
}
@property (retain) IBOutlet NSView* _view;
- (CVReturn)displayLinkRenderCallback:(const CVTimeStamp *)timeStamp;
- (void) render;
- (void) drawMeshesInContext:(CGLContextObj)cgl_ctx;
- (void) createGLResourcesInContext:(CGLContextObj)cgl_ctx;
- (void) deleteGLResourcesInContext:(CGLContextObj)cgl_ctx;
- (void) loadTexturesInContext:(CGLContextObj)cgl_ctx withModelPath:(NSString*) modelPath;
- (void) getBoundingBoxWithMinVector:(aiVector3D*) min maxVectr:(aiVector3D*) max;
- (void) getBoundingBoxForNode:(const aiNode*)nd minVector:(aiVector3D*) min maxVector:(aiVector3D*) max matrix:(aiMatrix4x4*) trafo;
@end

View file

@ -0,0 +1,808 @@
//
// MyDocument.m
// DisplayLinkAsyncMoviePlayer
//
// Created by vade on 10/26/10.
// Copyright __MyCompanyName__ 2010 . All rights reserved.
//
#import "cimport.h"
#import "config.h"
#import "MyDocument.h"
#import <OpenGL/CGLMacro.h>
#pragma mark -
#pragma mark Helper Functions
#define aisgl_min(x,y) (x<y?x:y)
#define aisgl_max(x,y) (y>x?y:x)
static void color4_to_float4(const aiColor4D *c, float f[4])
{
f[0] = c->r;
f[1] = c->g;
f[2] = c->b;
f[3] = c->a;
}
static void set_float4(float f[4], float a, float b, float c, float d)
{
f[0] = a;
f[1] = b;
f[2] = c;
f[3] = d;
}
#pragma mark -
#pragma mark CVDisplayLink Callback
static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink,const CVTimeStamp *inNow,const CVTimeStamp *inOutputTime,CVOptionFlags flagsIn,CVOptionFlags *flagsOut,void *displayLinkContext)
{
CVReturn error = [(MyDocument*) displayLinkContext displayLinkRenderCallback:inOutputTime];
return error;
}
#pragma mark -
@implementation MyDocument
@synthesize _view;
- (id)init
{
self = [super init];
if (self != nil)
{
// initialization code
}
return self;
}
- (NSString *)windowNibName
{
return @"MyDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)windowController
{
[super windowControllerDidLoadNib:windowController];
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAMultisample,
NSOpenGLPFASampleBuffers, 2,
(NSOpenGLPixelFormatAttribute) 0
};
_glPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
if(!_glPixelFormat)
NSLog(@"Error creating PF");
_glContext = [[NSOpenGLContext alloc] initWithFormat:_glPixelFormat shareContext:nil];
const GLint one = 1;
[_glContext setValues:&one forParameter:NSOpenGLCPSwapInterval];
[_glContext setView:_view];
// Set up initial GL state.
CGLContextObj cgl_ctx = (CGLContextObj)[_glContext CGLContextObj];
glEnable(GL_MULTISAMPLE);
glClearColor(0.3, 0.3, 0.3, 0.3);
// enable color tracking
//glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
GLfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
GLfloat diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
GLfloat ambient[] = {0.2, 0.2f, 0.2f, 0.2f};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
GLfloat position[] = { 1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, position);
glEnable(GL_LIGHT0);
// This is the only client state that always has to be set.
glEnableClientState(GL_VERTEX_ARRAY);
// end GL State setup.
// Display Link setup.
CVReturn error = kCVReturnSuccess;
error = CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
if(error == kCVReturnError)
NSLog(@"Error Creating DisplayLink");
error = CVDisplayLinkSetOutputCallback(_displayLink,MyDisplayLinkCallback, self);
if(error == kCVReturnError)
NSLog(@"Error Setting DisplayLink Callback");
error = CVDisplayLinkStart(_displayLink);
if(error == kCVReturnError)
NSLog(@"Error Starting DisplayLink");
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
[openPanel beginSheetModalForWindow:[_view window] completionHandler:^(NSInteger result)
{
if (result == NSOKButton)
{
[openPanel orderOut:self]; // close panel before we might present an error
if([[NSFileManager defaultManager] fileExistsAtPath:[openPanel filename]])
{
// Load our new path.
// only ever give us triangles.
aiPropertyStore* props = aiCreatePropertyStore();
aiSetImportPropertyInteger(props, AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT );
NSUInteger aiPostProccesFlags;
switch (2)
{
case 0:
aiPostProccesFlags = aiProcessPreset_TargetRealtime_Fast;
break;
case 1:
aiPostProccesFlags = aiProcessPreset_TargetRealtime_Quality;
break;
case 2:
aiPostProccesFlags = aiProcessPreset_TargetRealtime_MaxQuality;
break;
default:
aiPostProccesFlags = aiProcessPreset_TargetRealtime_MaxQuality;
break;
}
// aiProcess_FlipUVs is needed for VAO / VBOs, not sure why.
_scene = (aiScene*) aiImportFileExWithProperties([[openPanel filename] cStringUsingEncoding:[NSString defaultCStringEncoding]], aiPostProccesFlags | aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_PreTransformVertices | 0, NULL, props);
aiReleasePropertyStore(props);
if (_scene)
{
textureDictionary = [[NSMutableDictionary alloc] initWithCapacity:5];
// Why do I need to cast this !?
CGLContextObj cgl_ctx = (CGLContextObj)[_glContext CGLContextObj];
CGLLockContext(cgl_ctx);
[self loadTexturesInContext:cgl_ctx withModelPath:[[openPanel filename] stringByStandardizingPath]];
//NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:cgl_ctx], @"context", [self.inputModelPath stringByStandardizingPath], @"path", nil ];
//[self performSelectorInBackground:@selector(loadTexturesInBackground:) withObject:userInfo];
[self getBoundingBoxWithMinVector:&scene_min maxVectr:&scene_max];
scene_center.x = (scene_min.x + scene_max.x) / 2.0f;
scene_center.y = (scene_min.y + scene_max.y) / 2.0f;
scene_center.z = (scene_min.z + scene_max.z) / 2.0f;
// optional normalized scaling
normalizedScale = scene_max.x-scene_min.x;
normalizedScale = aisgl_max(scene_max.y - scene_min.y,normalizedScale);
normalizedScale = aisgl_max(scene_max.z - scene_min.z,normalizedScale);
normalizedScale = 1.f / normalizedScale;
if(_scene->HasAnimations())
NSLog(@"scene has animations");
[self createGLResourcesInContext:cgl_ctx];
CGLUnlockContext(cgl_ctx);
}
}
}
}]; // end block handler
}
- (void) close
{
CVDisplayLinkStop(_displayLink);
CVDisplayLinkRelease(_displayLink);
if(_scene)
{
aiReleaseImport(_scene);
_scene = NULL;
CGLContextObj cgl_ctx = (CGLContextObj)[_glContext CGLContextObj];
glDeleteTextures([textureDictionary count], textureIds);
[textureDictionary release];
textureDictionary = nil;
free(textureIds);
textureIds = NULL;
[self deleteGLResourcesInContext:cgl_ctx];
}
[_glContext release];
_glContext = nil;
[_glPixelFormat release];
_glPixelFormat = nil;
[super close];
}
- (CVReturn)displayLinkRenderCallback:(const CVTimeStamp *)timeStamp
{
CVReturn rv = kCVReturnError;
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
{
[self render];
rv = kCVReturnSuccess;
}
[pool release];
return rv;
}
- (void) render
{
CGLContextObj cgl_ctx = (CGLContextObj)[_glContext CGLContextObj];
CGLLockContext(cgl_ctx);
[_glContext update];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, _view.frame.size.width, _view.frame.size.height);
GLfloat aspect = _view.frame.size.height/_view.frame.size.width;
glOrtho(-1, 1, - (aspect), aspect, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslated(0.0, 0.0, 1.0);
// Draw our GL model.
if(_scene)
{
glScaled(normalizedScale , normalizedScale, normalizedScale);
// center the model
glTranslated( -scene_center.x, -scene_center.y, -scene_center.z);
glScaled(2.0, 2.0, 2.0);
static float i = 0;
i+=0.5;
glRotated(i, 0, 1, 0);
[self drawMeshesInContext:cgl_ctx];
}
CGLUnlockContext(cgl_ctx);
CGLFlushDrawable(cgl_ctx);
}
#pragma mark -
#pragma mark Loading
// Inspired by LoadAsset() & CreateAssetData() from AssimpView D3D project
- (void) createGLResourcesInContext:(CGLContextObj)cgl_ctx
{
// create new mesh helpers for each mesh, will populate their data later.
modelMeshes = [[NSMutableArray alloc] initWithCapacity:_scene->mNumMeshes];
// create OpenGL buffers and populate them based on each meshes pertinant info.
for (unsigned int i = 0; i < _scene->mNumMeshes; ++i)
{
NSLog(@"%u", i);
// current mesh we are introspecting
const aiMesh* mesh = _scene->mMeshes[i];
// the current meshHelper we will be populating data into.
MeshHelper* meshHelper = [[MeshHelper alloc] init];
// Handle material info
aiMaterial* mtl = _scene->mMaterials[mesh->mMaterialIndex];
// Textures
int texIndex = 0;
aiString texPath;
if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))
{
NSString* textureKey = [NSString stringWithCString:texPath.data encoding:[NSString defaultCStringEncoding]];
//bind texture
NSNumber* textureNumber = (NSNumber*)[textureDictionary valueForKey:textureKey];
//NSLog(@"applyMaterialInContext: have texture %i", [textureNumber unsignedIntValue]);
meshHelper.textureID = [textureNumber unsignedIntValue];
}
else
meshHelper.textureID = 0;
// Colors
aiColor4D dcolor = aiColor4D(0.8f, 0.8f, 0.8f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &dcolor))
[meshHelper setDiffuseColor:&dcolor];
aiColor4D scolor = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &scolor))
[meshHelper setSpecularColor:&scolor];
aiColor4D acolor = aiColor4D(0.2f, 0.2f, 0.2f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &acolor))
[meshHelper setAmbientColor:&acolor];
aiColor4D ecolor = aiColor4D(0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &ecolor))
[meshHelper setEmissiveColor:&ecolor];
// Culling
unsigned int max = 1;
int two_sided;
if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
[meshHelper setTwoSided:YES];
else
[meshHelper setTwoSided:NO];
// Create a VBO for our vertices
GLuint vhandle;
glGenBuffers(1, &vhandle);
glBindBuffer(GL_ARRAY_BUFFER, vhandle);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * mesh->mNumVertices, NULL, GL_STATIC_DRAW);
// populate vertices
Vertex* verts = (Vertex*)glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
for (unsigned int x = 0; x < mesh->mNumVertices; ++x)
{
verts->vPosition = mesh->mVertices[x];
if (NULL == mesh->mNormals)
verts->vNormal = aiVector3D(0.0f,0.0f,0.0f);
else
verts->vNormal = mesh->mNormals[x];
if (NULL == mesh->mTangents)
{
verts->vTangent = aiVector3D(0.0f,0.0f,0.0f);
verts->vBitangent = aiVector3D(0.0f,0.0f,0.0f);
}
else
{
verts->vTangent = mesh->mTangents[x];
verts->vBitangent = mesh->mBitangents[x];
}
if (mesh->HasVertexColors(0))
{
verts->dColorDiffuse = mesh->mColors[0][x];
}
else
verts->dColorDiffuse = aiColor4D(1.0, 1.0, 1.0, 1.0);
// This varies slightly form Assimp View, we support the 3rd texture component.
if (mesh->HasTextureCoords(0))
verts->vTextureUV = mesh->mTextureCoords[0][x];
else
verts->vTextureUV = aiVector3D(0.5f,0.5f, 0.0f);
if (mesh->HasTextureCoords(1))
verts->vTextureUV2 = mesh->mTextureCoords[1][x];
else
verts->vTextureUV2 = aiVector3D(0.5f,0.5f, 0.0f);
// TODO: handle Bone indices and weights
/* if( mesh->HasBones())
{
unsigned char boneIndices[4] = { 0, 0, 0, 0 };
unsigned char boneWeights[4] = { 0, 0, 0, 0 };
ai_assert( weightsPerVertex[x].size() <= 4);
for( unsigned int a = 0; a < weightsPerVertex[x].size(); a++)
{
boneIndices[a] = weightsPerVertex[x][a].mVertexId;
boneWeights[a] = (unsigned char) (weightsPerVertex[x][a].mWeight * 255.0f);
}
memcpy( verts->mBoneIndices, boneIndices, sizeof( boneIndices));
memcpy( verts->mBoneWeights, boneWeights, sizeof( boneWeights));
}
else
*/
{
memset( verts->mBoneIndices, 0, sizeof( verts->mBoneIndices));
memset( verts->mBoneWeights, 0, sizeof( verts->mBoneWeights));
}
++verts;
}
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); //invalidates verts
glBindBuffer(GL_ARRAY_BUFFER, 0);
// set the mesh vertex buffer handle to our new vertex buffer.
meshHelper.vertexBuffer = vhandle;
// Create Index Buffer
// populate the index buffer.
NSUInteger nidx;
switch (mesh->mPrimitiveTypes)
{
case aiPrimitiveType_POINT:
nidx = 1;break;
case aiPrimitiveType_LINE:
nidx = 2;break;
case aiPrimitiveType_TRIANGLE:
nidx = 3;break;
default: assert(false);
}
// create the index buffer
GLuint ihandle;
glGenBuffers(1, &ihandle);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ihandle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * mesh->mNumFaces * nidx, NULL, GL_STATIC_DRAW);
unsigned int* indices = (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_ARB);
// now fill the index buffer
for (unsigned int x = 0; x < mesh->mNumFaces; ++x)
{
for (unsigned int a = 0; a < nidx; ++a)
{
// if(mesh->mFaces[x].mNumIndices != 3)
// NSLog(@"whoa don't have 3 indices...");
*indices++ = mesh->mFaces[x].mIndices[a];
}
}
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// set the mesh index buffer handle to our new index buffer.
meshHelper.indexBuffer = ihandle;
meshHelper.numIndices = mesh->mNumFaces * nidx;
// create the normal buffer. Assimp View creates a second normal buffer. Unsure why. Using only the interleaved normals for now.
// This is here for reference.
/* GLuint nhandle;
glGenBuffers(1, &nhandle);
glBindBuffer(GL_ARRAY_BUFFER, nhandle);
glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D)* mesh->mNumVertices, NULL, GL_STATIC_DRAW);
// populate normals
aiVector3D* normals = (aiVector3D*)glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
for (unsigned int x = 0; x < mesh->mNumVertices; ++x)
{
aiVector3D vNormal = mesh->mNormals[x];
*normals = vNormal;
++normals;
}
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); //invalidates verts
glBindBuffer(GL_ARRAY_BUFFER, 0);
meshHelper.normalBuffer = nhandle;
*/
// Create VAO and populate it
GLuint vaoHandle;
glGenVertexArraysAPPLE(1, &vaoHandle);
glBindVertexArrayAPPLE(vaoHandle);
glBindBuffer(GL_ARRAY_BUFFER, meshHelper.vertexBuffer);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(24));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(64));
//TODO: handle second texture
// VertexPointer ought to come last, apparently this is some optimization, since if its set once, first, it gets fiddled with every time something else is update.
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshHelper.indexBuffer);
glBindVertexArrayAPPLE(0);
// save the VAO handle into our mesh helper
meshHelper.vao = vaoHandle;
// Create the display list
GLuint list = glGenLists(1);
glNewList(list, GL_COMPILE);
float dc[4];
float sc[4];
float ac[4];
float emc[4];
// Material colors and properties
color4_to_float4([meshHelper diffuseColor], dc);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, dc);
color4_to_float4([meshHelper specularColor], sc);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, sc);
color4_to_float4([meshHelper ambientColor], ac);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ac);
color4_to_float4(meshHelper.emissiveColor, emc);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emc);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// Culling
if(meshHelper.twoSided)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
// Texture Binding
glBindTexture(GL_TEXTURE_2D, meshHelper.textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// This binds the whole VAO, inheriting all the buffer and client state. Weeee
glBindVertexArrayAPPLE(meshHelper.vao);
glDrawElements(GL_TRIANGLES, meshHelper.numIndices, GL_UNSIGNED_INT, 0);
glEndList();
meshHelper.displayList = list;
// Whew, done. Save all of this shit.
[modelMeshes addObject:meshHelper];
[meshHelper release];
}
}
- (void) deleteGLResourcesInContext:(CGLContextObj)cgl_ctx
{
for(MeshHelper* helper in modelMeshes)
{
const GLuint indexBuffer = helper.indexBuffer;
const GLuint vertexBuffer = helper.vertexBuffer;
const GLuint normalBuffer = helper.normalBuffer;
const GLuint vaoHandle = helper.vao;
const GLuint dlist = helper.displayList;
glDeleteBuffers(1, &vertexBuffer);
glDeleteBuffers(1, &indexBuffer);
glDeleteBuffers(1, &normalBuffer);
glDeleteVertexArraysAPPLE(1, &vaoHandle);
glDeleteLists(1, dlist);
helper.indexBuffer = 0;
helper.vertexBuffer = 0;
helper.normalBuffer = 0;
helper.vao = 0;
helper.displayList = 0;
}
[modelMeshes release];
modelMeshes = nil;
}
- (void) drawMeshesInContext:(CGLContextObj)cgl_ctx
{
for(MeshHelper* helper in modelMeshes)
{
// Set up material state.
glCallList(helper.displayList);
}
}
- (void) loadTexturesInContext:(CGLContextObj)cgl_ctx withModelPath:(NSString*) modelPath
{
if (_scene->HasTextures())
{
NSLog(@"Support for meshes with embedded textures is not implemented");
return;
}
/* getTexture Filenames and Numb of Textures */
for (unsigned int m = 0; m < _scene->mNumMaterials; m++)
{
int texIndex = 0;
aiReturn texFound = AI_SUCCESS;
aiString path; // filename
// TODO: handle other aiTextureTypes
while (texFound == AI_SUCCESS)
{
texFound = _scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
NSString* texturePath = [NSString stringWithCString:path.data encoding:[NSString defaultCStringEncoding]];
// add our path to the texture and the index to our texture dictionary.
[textureDictionary setValue:[NSNumber numberWithUnsignedInt:texIndex] forKey:texturePath];
texIndex++;
}
}
textureIds = (GLuint*) malloc(sizeof(GLuint) * [textureDictionary count]); //new GLuint[ [textureDictionary count] ];
glGenTextures([textureDictionary count], textureIds);
NSLog(@"textureDictionary: %@", textureDictionary);
// create our textures, populate them, and alter our textureID value for the specific textureID we create.
// so we can modify while we enumerate...
NSDictionary *textureCopy = [textureDictionary copy];
// GCD attempt.
//dispatch_sync(_queue, ^{
int i = 0;
for(NSString* texturePath in textureCopy)
{
NSString* fullTexturePath = [[[modelPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:[texturePath stringByStandardizingPath]] stringByStandardizingPath];
NSLog(@"texturePath: %@", fullTexturePath);
NSImage* textureImage = [[NSImage alloc] initWithContentsOfFile:fullTexturePath];
if(textureImage)
{
//NSLog(@"Have Texture Image");
NSBitmapImageRep* bitmap = [NSBitmapImageRep alloc];
[textureImage lockFocus];
[bitmap initWithFocusedViewRect:NSMakeRect(0, 0, textureImage.size.width, textureImage.size.height)];
[textureImage unlockFocus];
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureIds[i]);
//glPixelStorei(GL_UNPACK_ROW_LENGTH, [bitmap pixelsWide]);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// generate mip maps
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// draw into our bitmap
int samplesPerPixel = [bitmap samplesPerPixel];
if(![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4))
{
glTexImage2D(GL_TEXTURE_2D,
0,
//samplesPerPixel == 4 ? GL_COMPRESSED_RGBA_S3TC_DXT3_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
[bitmap pixelsWide],
[bitmap pixelsHigh],
0,
samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
GL_UNSIGNED_BYTE,
[bitmap bitmapData]);
}
// update our dictionary to contain the proper textureID value (from out array of generated IDs)
[textureDictionary setValue:[NSNumber numberWithUnsignedInt:textureIds[i]] forKey:texturePath];
[bitmap release];
}
else
{
[textureDictionary removeObjectForKey:texturePath];
NSLog(@"Could not Load Texture: %@, removing reference to it.", fullTexturePath);
}
[textureImage release];
i++;
}
//});
[textureCopy release];
}
- (void) getBoundingBoxWithMinVector:(aiVector3D*) min maxVectr:(aiVector3D*) max
{
aiMatrix4x4 trafo;
aiIdentityMatrix4(&trafo);
min->x = min->y = min->z = 1e10f;
max->x = max->y = max->z = -1e10f;
[self getBoundingBoxForNode:_scene->mRootNode minVector:min maxVector:max matrix:&trafo];
}
- (void) getBoundingBoxForNode:(const aiNode*)nd minVector:(aiVector3D*) min maxVector:(aiVector3D*) max matrix:(aiMatrix4x4*) trafo
{
aiMatrix4x4 prev;
unsigned int n = 0, t;
prev = *trafo;
aiMultiplyMatrix4(trafo,&nd->mTransformation);
for (; n < nd->mNumMeshes; ++n)
{
const aiMesh* mesh = _scene->mMeshes[nd->mMeshes[n]];
for (t = 0; t < mesh->mNumVertices; ++t)
{
aiVector3D tmp = mesh->mVertices[t];
aiTransformVecByMatrix4(&tmp,trafo);
min->x = aisgl_min(min->x,tmp.x);
min->y = aisgl_min(min->y,tmp.y);
min->z = aisgl_min(min->z,tmp.z);
max->x = aisgl_max(max->x,tmp.x);
max->y = aisgl_max(max->y,tmp.y);
max->z = aisgl_max(max->z,tmp.z);
}
}
for (n = 0; n < nd->mNumChildren; ++n)
{
[self getBoundingBoxForNode:nd->mChildren[n] minVector:min maxVector:max matrix:trafo];
}
*trafo = prev;
}
@end

View file

@ -0,0 +1,22 @@
Mac OSX Assimp Sample, using OpenGL with VBOs
=============================================
Written & donated by drparallax.
See http://sourceforge.net/projects/assimp/forums/forum/817654/topic/3917829
How to build:
-------------
- compile Assimp as static library, copy the generated libassimp.a right here.
- copy the Assimp headers from ./../../include to ./include
- open the XCode project file and build it
Troubleshooting:
----------------
- OSX workspaces are not updated too frequently, so same files may be missing.
If you have any problems which you can't solve on your own,
please report them on the thread above.

View file

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>binary</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/octet-stream</string>
</array>
<key>CFBundleTypeName</key>
<string>Binary</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>NSDocumentClass</key>
<string>MyDocument</string>
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>sqlite</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/octet-stream</string>
</array>
<key>CFBundleTypeName</key>
<string>SQLite</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>NSDocumentClass</key>
<string>MyDocument</string>
<key>NSPersistentStoreTypeKey</key>
<string>SQLite</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>xml</string>
</array>
<key>CFBundleTypeIconFile</key>
<string></string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>text/xml</string>
</array>
<key>CFBundleTypeName</key>
<string>XML</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>????</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>NSDocumentClass</key>
<string>MyDocument</string>
<key>NSPersistentStoreTypeKey</key>
<string>XML</string>
</dict>
</array>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View file

@ -0,0 +1,478 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 45;
objects = {
/* Begin PBXBuildFile section */
1B0E9A901279ED43003108E7 /* libassimp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B0E9A8F1279ED43003108E7 /* libassimp.a */; };
1B0E9A951279EDCD003108E7 /* ModelLoaderHelperClasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1B0E9A941279EDCD003108E7 /* ModelLoaderHelperClasses.mm */; };
1B0E9B1A1279F107003108E7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B0E9B191279F107003108E7 /* libz.dylib */; };
1BDF446B127772AF00D3E723 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1BDF446A127772AF00D3E723 /* OpenGL.framework */; };
1BDF446F127772AF00D3E723 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1BDF446E127772AF00D3E723 /* Quartz.framework */; };
2F7446AB0DB6BCF400F9684A /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2F7446A70DB6BCF400F9684A /* MainMenu.xib */; };
2F7446AC0DB6BCF400F9684A /* MyDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2F7446A90DB6BCF400F9684A /* MyDocument.xib */; };
775BDEF1067A8BF0009058FE /* MyDocument.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = 775BDEF0067A8BF0009058FE /* MyDocument.xcdatamodel */; };
775DFF38067A968500C5B868 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */; };
8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165FFE840EACC02AAC07 /* InfoPlist.strings */; };
8D15AC310486D014006FF6A4 /* MyDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4ACFDCFA73011CA2CEA /* MyDocument.mm */; settings = {ATTRIBUTES = (); }; };
8D15AC320486D014006FF6A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4B0FDCFA73011CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
C75BB4F617EE0B64004F0260 /* color4.inl in Resources */ = {isa = PBXBuildFile; fileRef = C75BB4F117EE0B64004F0260 /* color4.inl */; };
C75BB4F717EE0B64004F0260 /* quaternion.inl in Resources */ = {isa = PBXBuildFile; fileRef = C75BB4F517EE0B64004F0260 /* quaternion.inl */; };
C75BB51417EE0B75004F0260 /* material.inl in Resources */ = {isa = PBXBuildFile; fileRef = C75BB50317EE0B75004F0260 /* material.inl */; };
C75BB51517EE0B75004F0260 /* matrix3x3.inl in Resources */ = {isa = PBXBuildFile; fileRef = C75BB50517EE0B75004F0260 /* matrix3x3.inl */; };
C75BB51617EE0B75004F0260 /* matrix4x4.inl in Resources */ = {isa = PBXBuildFile; fileRef = C75BB50717EE0B75004F0260 /* matrix4x4.inl */; };
C75BB51717EE0B75004F0260 /* vector2.inl in Resources */ = {isa = PBXBuildFile; fileRef = C75BB51017EE0B75004F0260 /* vector2.inl */; };
C75BB51817EE0B75004F0260 /* vector3.inl in Resources */ = {isa = PBXBuildFile; fileRef = C75BB51217EE0B75004F0260 /* vector3.inl */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
089C1660FE840EACC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
1B0E9A8F1279ED43003108E7 /* libassimp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libassimp.a; sourceTree = "<group>"; };
1B0E9A931279EDCD003108E7 /* ModelLoaderHelperClasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModelLoaderHelperClasses.h; sourceTree = "<group>"; };
1B0E9A941279EDCD003108E7 /* ModelLoaderHelperClasses.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ModelLoaderHelperClasses.mm; sourceTree = "<group>"; };
1B0E9AFD1279F006003108E7 /* poppack1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = poppack1.h; path = "/Users/vade/Asset Import/include/Compiler/poppack1.h"; sourceTree = "<absolute>"; };
1B0E9AFE1279F006003108E7 /* pushpack1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pushpack1.h; path = "/Users/vade/Asset Import/include/Compiler/pushpack1.h"; sourceTree = "<absolute>"; };
1B0E9B191279F107003108E7 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
1BDF446A127772AF00D3E723 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
1BDF446E127772AF00D3E723 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree = SDKROOT; };
2A37F4ACFDCFA73011CA2CEA /* MyDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MyDocument.mm; sourceTree = "<group>"; };
2A37F4AEFDCFA73011CA2CEA /* MyDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyDocument.h; sourceTree = "<group>"; };
2A37F4B0FDCFA73011CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
2A37F4BAFDCFA73011CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = "<group>"; };
2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
2F7446A80DB6BCF400F9684A /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
2F7446AA0DB6BCF400F9684A /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MyDocument.xib; sourceTree = "<group>"; };
32DBCF750370BD2300C91783 /* SimpleAssimpViewX_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleAssimpViewX_Prefix.pch; sourceTree = "<group>"; };
775BDEF0067A8BF0009058FE /* MyDocument.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = MyDocument.xcdatamodel; sourceTree = "<group>"; };
7788DA0506752A1600599AAD /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
8D15AC360486D014006FF6A4 /* SimpleAssimpViewX-Info.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 4; path = "SimpleAssimpViewX-Info.plist"; sourceTree = "<group>"; };
8D15AC370486D014006FF6A4 /* SimpleAssimpViewX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleAssimpViewX.app; sourceTree = BUILT_PRODUCTS_DIR; };
C75BB4EA17EE0B64004F0260 /* ai_assert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ai_assert.h; sourceTree = "<group>"; };
C75BB4EB17EE0B64004F0260 /* anim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anim.h; sourceTree = "<group>"; };
C75BB4EC17EE0B64004F0260 /* camera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = camera.h; sourceTree = "<group>"; };
C75BB4ED17EE0B64004F0260 /* cexport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cexport.h; sourceTree = "<group>"; };
C75BB4EE17EE0B64004F0260 /* cfileio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cfileio.h; sourceTree = "<group>"; };
C75BB4EF17EE0B64004F0260 /* cimport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cimport.h; sourceTree = "<group>"; };
C75BB4F017EE0B64004F0260 /* color4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = color4.h; sourceTree = "<group>"; };
C75BB4F117EE0B64004F0260 /* color4.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = color4.inl; sourceTree = "<group>"; };
C75BB4F217EE0B64004F0260 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
C75BB4F317EE0B64004F0260 /* metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = metadata.h; sourceTree = "<group>"; };
C75BB4F417EE0B64004F0260 /* NullLogger.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = NullLogger.hpp; sourceTree = "<group>"; };
C75BB4F517EE0B64004F0260 /* quaternion.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = quaternion.inl; sourceTree = "<group>"; };
C75BB4F817EE0B75004F0260 /* DefaultLogger.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DefaultLogger.hpp; sourceTree = "<group>"; };
C75BB4F917EE0B75004F0260 /* defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defs.h; sourceTree = "<group>"; };
C75BB4FA17EE0B75004F0260 /* Exporter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Exporter.hpp; sourceTree = "<group>"; };
C75BB4FB17EE0B75004F0260 /* Importer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Importer.hpp; sourceTree = "<group>"; };
C75BB4FC17EE0B75004F0260 /* importerdesc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = importerdesc.h; sourceTree = "<group>"; };
C75BB4FD17EE0B75004F0260 /* IOStream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IOStream.hpp; sourceTree = "<group>"; };
C75BB4FE17EE0B75004F0260 /* IOSystem.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IOSystem.hpp; sourceTree = "<group>"; };
C75BB4FF17EE0B75004F0260 /* light.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = light.h; sourceTree = "<group>"; };
C75BB50017EE0B75004F0260 /* Logger.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Logger.hpp; sourceTree = "<group>"; };
C75BB50117EE0B75004F0260 /* LogStream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LogStream.hpp; sourceTree = "<group>"; };
C75BB50217EE0B75004F0260 /* material.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = material.h; sourceTree = "<group>"; };
C75BB50317EE0B75004F0260 /* material.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = material.inl; sourceTree = "<group>"; };
C75BB50417EE0B75004F0260 /* matrix3x3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix3x3.h; sourceTree = "<group>"; };
C75BB50517EE0B75004F0260 /* matrix3x3.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = matrix3x3.inl; sourceTree = "<group>"; };
C75BB50617EE0B75004F0260 /* matrix4x4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = matrix4x4.h; sourceTree = "<group>"; };
C75BB50717EE0B75004F0260 /* matrix4x4.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = matrix4x4.inl; sourceTree = "<group>"; };
C75BB50817EE0B75004F0260 /* mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mesh.h; sourceTree = "<group>"; };
C75BB50917EE0B75004F0260 /* postprocess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = postprocess.h; sourceTree = "<group>"; };
C75BB50A17EE0B75004F0260 /* ProgressHandler.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ProgressHandler.hpp; sourceTree = "<group>"; };
C75BB50B17EE0B75004F0260 /* quaternion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = quaternion.h; sourceTree = "<group>"; };
C75BB50C17EE0B75004F0260 /* scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scene.h; sourceTree = "<group>"; };
C75BB50D17EE0B75004F0260 /* texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = texture.h; sourceTree = "<group>"; };
C75BB50E17EE0B75004F0260 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
C75BB50F17EE0B75004F0260 /* vector2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vector2.h; sourceTree = "<group>"; };
C75BB51017EE0B75004F0260 /* vector2.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = vector2.inl; sourceTree = "<group>"; };
C75BB51117EE0B75004F0260 /* vector3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vector3.h; sourceTree = "<group>"; };
C75BB51217EE0B75004F0260 /* vector3.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = vector3.inl; sourceTree = "<group>"; };
C75BB51317EE0B75004F0260 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8D15AC330486D014006FF6A4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
775DFF38067A968500C5B868 /* Cocoa.framework in Frameworks */,
1BDF446B127772AF00D3E723 /* OpenGL.framework in Frameworks */,
1BDF446F127772AF00D3E723 /* Quartz.framework in Frameworks */,
1B0E9A901279ED43003108E7 /* libassimp.a in Frameworks */,
1B0E9B1A1279F107003108E7 /* libz.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */,
1BDF446A127772AF00D3E723 /* OpenGL.framework */,
1BDF446E127772AF00D3E723 /* Quartz.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
};
1058C7A8FEA54F5311CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */,
7788DA0506752A1600599AAD /* CoreData.framework */,
2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
19C28FB0FE9D524F11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8D15AC370486D014006FF6A4 /* SimpleAssimpViewX.app */,
);
name = Products;
sourceTree = "<group>";
};
1B0E9AD21279EFCC003108E7 /* include */ = {
isa = PBXGroup;
children = (
C75BB4F817EE0B75004F0260 /* DefaultLogger.hpp */,
C75BB4F917EE0B75004F0260 /* defs.h */,
C75BB4FA17EE0B75004F0260 /* Exporter.hpp */,
C75BB4FB17EE0B75004F0260 /* Importer.hpp */,
C75BB4FC17EE0B75004F0260 /* importerdesc.h */,
C75BB4FD17EE0B75004F0260 /* IOStream.hpp */,
C75BB4FE17EE0B75004F0260 /* IOSystem.hpp */,
C75BB4FF17EE0B75004F0260 /* light.h */,
C75BB50017EE0B75004F0260 /* Logger.hpp */,
C75BB50117EE0B75004F0260 /* LogStream.hpp */,
C75BB50217EE0B75004F0260 /* material.h */,
C75BB50317EE0B75004F0260 /* material.inl */,
C75BB50417EE0B75004F0260 /* matrix3x3.h */,
C75BB50517EE0B75004F0260 /* matrix3x3.inl */,
C75BB50617EE0B75004F0260 /* matrix4x4.h */,
C75BB50717EE0B75004F0260 /* matrix4x4.inl */,
C75BB50817EE0B75004F0260 /* mesh.h */,
C75BB50917EE0B75004F0260 /* postprocess.h */,
C75BB50A17EE0B75004F0260 /* ProgressHandler.hpp */,
C75BB50B17EE0B75004F0260 /* quaternion.h */,
C75BB50C17EE0B75004F0260 /* scene.h */,
C75BB50D17EE0B75004F0260 /* texture.h */,
C75BB50E17EE0B75004F0260 /* types.h */,
C75BB50F17EE0B75004F0260 /* vector2.h */,
C75BB51017EE0B75004F0260 /* vector2.inl */,
C75BB51117EE0B75004F0260 /* vector3.h */,
C75BB51217EE0B75004F0260 /* vector3.inl */,
C75BB51317EE0B75004F0260 /* version.h */,
C75BB4EA17EE0B64004F0260 /* ai_assert.h */,
C75BB4EB17EE0B64004F0260 /* anim.h */,
C75BB4EC17EE0B64004F0260 /* camera.h */,
C75BB4ED17EE0B64004F0260 /* cexport.h */,
C75BB4EE17EE0B64004F0260 /* cfileio.h */,
C75BB4EF17EE0B64004F0260 /* cimport.h */,
C75BB4F017EE0B64004F0260 /* color4.h */,
C75BB4F117EE0B64004F0260 /* color4.inl */,
C75BB4F217EE0B64004F0260 /* config.h */,
C75BB4F317EE0B64004F0260 /* metadata.h */,
C75BB4F417EE0B64004F0260 /* NullLogger.hpp */,
C75BB4F517EE0B64004F0260 /* quaternion.inl */,
1B0E9AFC1279F006003108E7 /* Compiler */,
);
path = include;
sourceTree = "<group>";
};
1B0E9AFC1279F006003108E7 /* Compiler */ = {
isa = PBXGroup;
children = (
1B0E9AFD1279F006003108E7 /* poppack1.h */,
1B0E9AFE1279F006003108E7 /* pushpack1.h */,
);
name = Compiler;
path = "/Users/vade/Asset Import/include/Compiler";
sourceTree = "<absolute>";
};
2A37F4AAFDCFA73011CA2CEA /* DisplayLinkAsyncMoviePlayer */ = {
isa = PBXGroup;
children = (
E1B74B1A0667B4A90069E3BA /* Models */,
2A37F4ABFDCFA73011CA2CEA /* Classes */,
1B0E9A8F1279ED43003108E7 /* libassimp.a */,
1B0E9AD21279EFCC003108E7 /* include */,
2A37F4AFFDCFA73011CA2CEA /* Other Sources */,
2A37F4B8FDCFA73011CA2CEA /* Resources */,
2A37F4C3FDCFA73011CA2CEA /* Frameworks */,
19C28FB0FE9D524F11CA2CBB /* Products */,
1B0E9B191279F107003108E7 /* libz.dylib */,
);
name = DisplayLinkAsyncMoviePlayer;
sourceTree = "<group>";
};
2A37F4ABFDCFA73011CA2CEA /* Classes */ = {
isa = PBXGroup;
children = (
2A37F4AEFDCFA73011CA2CEA /* MyDocument.h */,
2A37F4ACFDCFA73011CA2CEA /* MyDocument.mm */,
1B0E9A931279EDCD003108E7 /* ModelLoaderHelperClasses.h */,
1B0E9A941279EDCD003108E7 /* ModelLoaderHelperClasses.mm */,
);
name = Classes;
sourceTree = "<group>";
};
2A37F4AFFDCFA73011CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
32DBCF750370BD2300C91783 /* SimpleAssimpViewX_Prefix.pch */,
2A37F4B0FDCFA73011CA2CEA /* main.m */,
);
name = "Other Sources";
sourceTree = "<group>";
};
2A37F4B8FDCFA73011CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
2F7446A70DB6BCF400F9684A /* MainMenu.xib */,
2F7446A90DB6BCF400F9684A /* MyDocument.xib */,
2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */,
8D15AC360486D014006FF6A4 /* SimpleAssimpViewX-Info.plist */,
089C165FFE840EACC02AAC07 /* InfoPlist.strings */,
);
name = Resources;
sourceTree = "<group>";
};
2A37F4C3FDCFA73011CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */,
1058C7A8FEA54F5311CA2CBB /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
E1B74B1A0667B4A90069E3BA /* Models */ = {
isa = PBXGroup;
children = (
775BDEF0067A8BF0009058FE /* MyDocument.xcdatamodel */,
);
name = Models;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8D15AC270486D014006FF6A4 /* SimpleAssimpViewX */ = {
isa = PBXNativeTarget;
buildConfigurationList = 26FC0AA50875C8B900E6366F /* Build configuration list for PBXNativeTarget "SimpleAssimpViewX" */;
buildPhases = (
8D15AC2B0486D014006FF6A4 /* Resources */,
8D15AC300486D014006FF6A4 /* Sources */,
8D15AC330486D014006FF6A4 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = SimpleAssimpViewX;
productInstallPath = "$(HOME)/Applications";
productName = DisplayLinkAsyncMoviePlayer;
productReference = 8D15AC370486D014006FF6A4 /* SimpleAssimpViewX.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
2A37F4A9FDCFA73011CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
};
buildConfigurationList = 26FC0AA90875C8B900E6366F /* Build configuration list for PBXProject "SimpleAssimpViewX" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 2A37F4AAFDCFA73011CA2CEA /* DisplayLinkAsyncMoviePlayer */;
projectDirPath = "";
projectRoot = "";
targets = (
8D15AC270486D014006FF6A4 /* SimpleAssimpViewX */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8D15AC2B0486D014006FF6A4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */,
8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */,
2F7446AB0DB6BCF400F9684A /* MainMenu.xib in Resources */,
2F7446AC0DB6BCF400F9684A /* MyDocument.xib in Resources */,
C75BB4F617EE0B64004F0260 /* color4.inl in Resources */,
C75BB4F717EE0B64004F0260 /* quaternion.inl in Resources */,
C75BB51417EE0B75004F0260 /* material.inl in Resources */,
C75BB51517EE0B75004F0260 /* matrix3x3.inl in Resources */,
C75BB51617EE0B75004F0260 /* matrix4x4.inl in Resources */,
C75BB51717EE0B75004F0260 /* vector2.inl in Resources */,
C75BB51817EE0B75004F0260 /* vector3.inl in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D15AC300486D014006FF6A4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8D15AC310486D014006FF6A4 /* MyDocument.mm in Sources */,
8D15AC320486D014006FF6A4 /* main.m in Sources */,
775BDEF1067A8BF0009058FE /* MyDocument.xcdatamodel in Sources */,
1B0E9A951279EDCD003108E7 /* ModelLoaderHelperClasses.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
089C165FFE840EACC02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C1660FE840EACC02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */ = {
isa = PBXVariantGroup;
children = (
2A37F4BAFDCFA73011CA2CEA /* English */,
);
name = Credits.rtf;
sourceTree = "<group>";
};
2F7446A70DB6BCF400F9684A /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
2F7446A80DB6BCF400F9684A /* English */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
2F7446A90DB6BCF400F9684A /* MyDocument.xib */ = {
isa = PBXVariantGroup;
children = (
2F7446AA0DB6BCF400F9684A /* English */,
);
name = MyDocument.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
26FC0AA60875C8B900E6366F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = SimpleAssimpViewX_Prefix.pch;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"/**";
INFOPLIST_FILE = "SimpleAssimpViewX-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)\"",
);
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = SimpleAssimpViewX;
VALID_ARCHS = "x86_64 i386";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
26FC0AA70875C8B900E6366F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)\"";
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = SimpleAssimpViewX_Prefix.pch;
HEADER_SEARCH_PATHS = "\"$(SRCROOT)\"/**";
INFOPLIST_FILE = "SimpleAssimpViewX-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)\"",
);
ONLY_ACTIVE_ARCH = NO;
PRODUCT_NAME = SimpleAssimpViewX;
VALID_ARCHS = "x86_64 i386";
WRAPPER_EXTENSION = app;
};
name = Release;
};
26FC0AAA0875C8B900E6366F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = macosx;
};
name = Debug;
};
26FC0AAB0875C8B900E6366F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = macosx;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
26FC0AA50875C8B900E6366F /* Build configuration list for PBXNativeTarget "SimpleAssimpViewX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
26FC0AA60875C8B900E6366F /* Debug */,
26FC0AA70875C8B900E6366F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
26FC0AA90875C8B900E6366F /* Build configuration list for PBXProject "SimpleAssimpViewX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
26FC0AAA0875C8B900E6366F /* Debug */,
26FC0AAB0875C8B900E6366F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 2A37F4A9FDCFA73011CA2CEA /* Project object */;
}

View file

@ -0,0 +1,9 @@
//
// Prefix header for all source files of the 'DisplayLinkAsyncMoviePlayer' target in the 'DisplayLinkAsyncMoviePlayer' project
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <Cocoa/Cocoa.h>
#endif

View file

@ -0,0 +1,14 @@
//
// main.m
// DisplayLinkAsyncMoviePlayer
//
// Created by vade on 10/26/10.
// Copyright __MyCompanyName__ 2010 . All rights reserved.
//
#import <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **) argv);
}

View file

@ -0,0 +1,58 @@
SET(SAMPLE_PROJECT_NAME assimp_simpleogl)
FIND_PACKAGE(OpenGL)
FIND_PACKAGE(GLUT)
IF ( MSVC )
SET(M_LIB)
ELSE ()
find_library(M_LIB m)
ENDIF ()
IF ( NOT GLUT_FOUND )
IF ( MSVC )
SET ( GLUT_FOUND 1 )
SET ( GLUT_INCLUDE_DIR ${Assimp_SOURCE_DIR}/samples/freeglut/ )
SET ( GLUT_LIBRARIES ${Assimp_SOURCE_DIR}/samples/freeglut/lib/freeglut.lib )
ELSE ()
MESSAGE( WARNING "Please install glut." )
ENDIF ()
ENDIF ()
# Used for usage and error messages in the program.
ADD_COMPILE_DEFINITIONS(ASSIMP_VERSION="${ASSIMP_VERSION}")
ADD_COMPILE_DEFINITIONS(PROJECT_NAME="${SAMPLE_PROJECT_NAME}")
if ( MSVC )
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
endif ()
INCLUDE_DIRECTORIES(
${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code
${OPENGL_INCLUDE_DIR}
${GLUT_INCLUDE_DIR}
${Assimp_SOURCE_DIR}/samples/freeglut/include
)
LINK_DIRECTORIES(
${Assimp_BINARY_DIR}
${Assimp_BINARY_DIR}/lib
)
ADD_EXECUTABLE( ${SAMPLE_PROJECT_NAME}
Sample_SimpleOpenGL.c
)
TARGET_USE_COMMON_OUTPUT_DIRECTORY(${SAMPLE_PROJECT_NAME})
SET_PROPERTY(TARGET ${SAMPLE_PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
TARGET_LINK_LIBRARIES( ${SAMPLE_PROJECT_NAME} assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${M_LIB} )
SET_TARGET_PROPERTIES( ${SAMPLE_PROJECT_NAME} PROPERTIES
OUTPUT_NAME ${SAMPLE_PROJECT_NAME}
)
INSTALL( TARGETS ${SAMPLE_PROJECT_NAME}
DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
)

View file

@ -0,0 +1,448 @@
/* ----------------------------------------------------------------------------
// Simple sample to prove that Assimp is easy to use with OpenGL.
// It takes a file name as command line parameter, loads it using standard
// settings and displays it.
//
// If you intend to _use_ this code sample in your app, do yourself a favour
// and replace immediate mode calls with VBOs ...
//
// The vc8 solution links against assimp-release-dll_win32 - be sure to
// have this configuration built.
// ----------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#ifdef __APPLE__
#include <freeglut.h>
#else
#include <GL/freeglut.h>
#endif
/* assimp include files. These three are usually needed. */
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#define COMMAND_USAGE "--usage"
/* ---------------------------------------------------------------------------- */
inline static void print_run_command(const char* command_name) {
printf("Run '%s %s' for more information.\n",
PROJECT_NAME, command_name);
}
/* ---------------------------------------------------------------------------- */
inline static void print_error(const char* msg) {
printf("ERROR: %s\n", msg);
}
#define NEW_LINE "\n"
#define DOUBLE_NEW_LINE NEW_LINE NEW_LINE
/* ---------------------------------------------------------------------------- */
inline static void print_usage() {
static const char* usage_format =
"Usage: "
PROJECT_NAME
" <file>" DOUBLE_NEW_LINE
"where:" DOUBLE_NEW_LINE
" %-10s %s" DOUBLE_NEW_LINE
"options:" DOUBLE_NEW_LINE
" %-10s %s" DOUBLE_NEW_LINE;
printf(usage_format,
// where
"file", "The input model file to load.",
// options
COMMAND_USAGE, "Display usage.");
}
/* the global Assimp scene object */
const C_STRUCT aiScene* scene = NULL;
GLuint scene_list = 0;
C_STRUCT aiVector3D scene_min, scene_max, scene_center;
/* current rotation angle */
static float angle = 0.f;
#define aisgl_min(x,y) (x<y?x:y)
#define aisgl_max(x,y) (y>x?y:x)
/* ---------------------------------------------------------------------------- */
void reshape(int width, int height)
{
const double aspectRatio = (float) width / height, fieldOfView = 45.0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fieldOfView, aspectRatio,
1.0, 1000.0); /* Znear and Zfar */
glViewport(0, 0, width, height);
}
/* ---------------------------------------------------------------------------- */
void get_bounding_box_for_node (const C_STRUCT aiNode* nd,
C_STRUCT aiVector3D* min,
C_STRUCT aiVector3D* max,
C_STRUCT aiMatrix4x4* trafo
){
C_STRUCT aiMatrix4x4 prev;
unsigned int n = 0, t;
prev = *trafo;
aiMultiplyMatrix4(trafo,&nd->mTransformation);
for (; n < nd->mNumMeshes; ++n) {
const C_STRUCT aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
for (t = 0; t < mesh->mNumVertices; ++t) {
C_STRUCT aiVector3D tmp = mesh->mVertices[t];
aiTransformVecByMatrix4(&tmp,trafo);
min->x = aisgl_min(min->x,tmp.x);
min->y = aisgl_min(min->y,tmp.y);
min->z = aisgl_min(min->z,tmp.z);
max->x = aisgl_max(max->x,tmp.x);
max->y = aisgl_max(max->y,tmp.y);
max->z = aisgl_max(max->z,tmp.z);
}
}
for (n = 0; n < nd->mNumChildren; ++n) {
get_bounding_box_for_node(nd->mChildren[n],min,max,trafo);
}
*trafo = prev;
}
/* ---------------------------------------------------------------------------- */
void get_bounding_box(C_STRUCT aiVector3D* min, C_STRUCT aiVector3D* max)
{
C_STRUCT aiMatrix4x4 trafo;
aiIdentityMatrix4(&trafo);
min->x = min->y = min->z = 1e10f;
max->x = max->y = max->z = -1e10f;
get_bounding_box_for_node(scene->mRootNode,min,max,&trafo);
}
/* ---------------------------------------------------------------------------- */
void color4_to_float4(const C_STRUCT aiColor4D *c, float f[4])
{
f[0] = c->r;
f[1] = c->g;
f[2] = c->b;
f[3] = c->a;
}
/* ---------------------------------------------------------------------------- */
void set_float4(float f[4], float a, float b, float c, float d)
{
f[0] = a;
f[1] = b;
f[2] = c;
f[3] = d;
}
/* ---------------------------------------------------------------------------- */
void apply_material(const C_STRUCT aiMaterial *mtl)
{
float c[4];
GLenum fill_mode;
int ret1, ret2;
C_STRUCT aiColor4D diffuse;
C_STRUCT aiColor4D specular;
C_STRUCT aiColor4D ambient;
C_STRUCT aiColor4D emission;
ai_real shininess, strength;
int two_sided;
int wireframe;
unsigned int max;
set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
color4_to_float4(&diffuse, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
color4_to_float4(&specular, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
color4_to_float4(&ambient, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
color4_to_float4(&emission, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);
max = 1;
ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
if(ret1 == AI_SUCCESS) {
max = 1;
ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
if(ret2 == AI_SUCCESS)
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
else
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
}
else {
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
}
max = 1;
if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
fill_mode = wireframe ? GL_LINE : GL_FILL;
else
fill_mode = GL_FILL;
glPolygonMode(GL_FRONT_AND_BACK, fill_mode);
max = 1;
if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
glDisable(GL_CULL_FACE);
else
glEnable(GL_CULL_FACE);
}
/* ---------------------------------------------------------------------------- */
void recursive_render (const C_STRUCT aiScene *sc, const C_STRUCT aiNode* nd)
{
unsigned int i;
unsigned int n = 0, t;
C_STRUCT aiMatrix4x4 m = nd->mTransformation;
/* update transform */
aiTransposeMatrix4(&m);
glPushMatrix();
glMultMatrixf((float*)&m);
/* draw all meshes assigned to this node */
for (; n < nd->mNumMeshes; ++n) {
const C_STRUCT aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
if(mesh->mNormals == NULL) {
glDisable(GL_LIGHTING);
} else {
glEnable(GL_LIGHTING);
}
for (t = 0; t < mesh->mNumFaces; ++t) {
const C_STRUCT aiFace* face = &mesh->mFaces[t];
GLenum face_mode;
switch(face->mNumIndices) {
case 1: face_mode = GL_POINTS; break;
case 2: face_mode = GL_LINES; break;
case 3: face_mode = GL_TRIANGLES; break;
default: face_mode = GL_POLYGON; break;
}
glBegin(face_mode);
for(i = 0; i < face->mNumIndices; i++) {
int index = face->mIndices[i];
if(mesh->mColors[0] != NULL)
glColor4fv((GLfloat*)&mesh->mColors[0][index]);
if(mesh->mNormals != NULL)
glNormal3fv(&mesh->mNormals[index].x);
glVertex3fv(&mesh->mVertices[index].x);
}
glEnd();
}
}
/* draw all children */
for (n = 0; n < nd->mNumChildren; ++n) {
recursive_render(sc, nd->mChildren[n]);
}
glPopMatrix();
}
/* ---------------------------------------------------------------------------- */
void do_motion (void)
{
static GLint prev_time = 0;
static GLint prev_fps_time = 0;
static int frames = 0;
int time = glutGet(GLUT_ELAPSED_TIME);
angle += (float)((time-prev_time)*0.01);
prev_time = time;
frames += 1;
if ((time - prev_fps_time) > 1000) /* update every seconds */
{
int current_fps = frames * 1000 / (time - prev_fps_time);
printf("%d fps\n", current_fps);
frames = 0;
prev_fps_time = time;
}
glutPostRedisplay ();
}
/* ---------------------------------------------------------------------------- */
void display(void)
{
float tmp;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f);
/* rotate it around the y axis */
glRotatef(angle,0.f,1.f,0.f);
/* scale the whole asset to fit into our view frustum */
tmp = scene_max.x-scene_min.x;
tmp = aisgl_max(scene_max.y - scene_min.y,tmp);
tmp = aisgl_max(scene_max.z - scene_min.z,tmp);
tmp = 1.f / tmp;
glScalef(tmp, tmp, tmp);
/* center the model */
glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z );
/* if the display list has not been made yet, create a new one and
fill it with scene contents */
if(scene_list == 0) {
scene_list = glGenLists(1);
glNewList(scene_list, GL_COMPILE);
/* now begin at the root node of the imported data and traverse
the scenegraph by multiplying subsequent local transforms
together on GL's matrix stack. */
recursive_render(scene, scene->mRootNode);
glEndList();
}
glCallList(scene_list);
glutSwapBuffers();
do_motion();
}
/* ---------------------------------------------------------------------------- */
int loadasset (const char* path)
{
/* we are taking one of the postprocessing presets to avoid
spelling out 20+ single postprocessing flags here. */
scene = aiImportFile(path,aiProcessPreset_TargetRealtime_MaxQuality);
if (scene) {
get_bounding_box(&scene_min,&scene_max);
scene_center.x = (scene_min.x + scene_max.x) / 2.0f;
scene_center.y = (scene_min.y + scene_max.y) / 2.0f;
scene_center.z = (scene_min.z + scene_max.z) / 2.0f;
return 0;
}
return 1;
}
/* ---------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
const char* model_file = NULL;
C_STRUCT aiLogStream stream;
if (argc < 2) {
print_error("No input model file specified.");
print_run_command(COMMAND_USAGE);
return EXIT_FAILURE;
}
// Find and execute available commands entered by the user.
for (int i = 1; i < argc; ++i) {
if (!strncmp(argv[i], COMMAND_USAGE, strlen(COMMAND_USAGE))) {
print_usage();
return EXIT_SUCCESS;
}
}
// Check and validate the specified model file extension.
model_file = argv[1];
const char* extension = strrchr(model_file, '.');
if (!extension) {
print_error("Please provide a file with a valid extension.");
return EXIT_FAILURE;
}
if (AI_FALSE == aiIsExtensionSupported(extension)) {
print_error("The specified model file extension is currently "
"unsupported in Assimp " ASSIMP_VERSION ".");
return EXIT_FAILURE;
}
glutInitWindowSize(900,600);
glutInitWindowPosition(100,100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutCreateWindow("Assimp - Very simple OpenGL sample");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
/* get a handle to the predefined STDOUT log stream and attach
it to the logging system. It remains active for all further
calls to aiImportFile(Ex) and aiApplyPostProcessing. */
stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
aiAttachLogStream(&stream);
/* ... same procedure, but this stream now writes the
log messages to assimp_log.txt */
stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
aiAttachLogStream(&stream);
// Load the model file.
if(0 != loadasset(model_file)) {
print_error("Failed to load model. Please ensure that the specified file exists.");
aiDetachAllLogStreams();
return EXIT_FAILURE;
}
glClearColor(0.1f,0.1f,0.1f,1.f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); /* Uses default lighting parameters */
glEnable(GL_DEPTH_TEST);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_NORMALIZE);
/* XXX docs say all polygons are emitted CCW, but tests show that some aren't. */
if(getenv("MODEL_IS_BROKEN"))
glFrontFace(GL_CW);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glutGet(GLUT_ELAPSED_TIME);
glutMainLoop();
/* cleanup - calling 'aiReleaseImport' is important, as the library
keeps internal resources until the scene is freed again. Not
doing so can cause severe resource leaking. */
aiReleaseImport(scene);
/* We added a log stream to the library, it's our job to disable it
again. This will definitely release the last resources allocated
by Assimp.*/
aiDetachAllLogStreams();
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,51 @@
FIND_PACKAGE(DirectX)
IF ( MSVC )
SET(M_LIB)
ENDIF ()
if ( MSVC )
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
REMOVE_DEFINITIONS( -DUNICODE -D_UNICODE )
endif ()
ADD_COMPILE_DEFINITIONS(SHADER_PATH="${CMAKE_CURRENT_SOURCE_DIR}/SimpleTexturedDirectx11/")
INCLUDE_DIRECTORIES(
${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code
${SAMPLES_SHARED_CODE_DIR}
)
LINK_DIRECTORIES(
${Assimp_BINARY_DIR}
${Assimp_BINARY_DIR}/lib
)
ADD_EXECUTABLE( assimp_simpletextureddirectx11 WIN32
SimpleTexturedDirectx11/Mesh.h
SimpleTexturedDirectx11/ModelLoader.cpp
SimpleTexturedDirectx11/ModelLoader.h
#SimpleTexturedDirectx11/PixelShader.hlsl
SimpleTexturedDirectx11/TextureLoader.cpp
SimpleTexturedDirectx11/TextureLoader.h
#SimpleTexturedDirectx11/VertexShader.hlsl
SimpleTexturedDirectx11/main.cpp
SimpleTexturedDirectx11/SafeRelease.hpp
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.cpp
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.h
)
TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp_simpletextureddirectx11)
SET_PROPERTY(TARGET assimp_simpletextureddirectx11 PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
TARGET_LINK_LIBRARIES( assimp_simpletextureddirectx11 assimp comctl32.lib winmm.lib )
SET_TARGET_PROPERTIES( assimp_simpletextureddirectx11 PROPERTIES
OUTPUT_NAME assimp_simpletextureddirectx11
)
INSTALL( TARGETS assimp_simpletextureddirectx11
DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
)

View file

@ -0,0 +1,107 @@
#ifndef MESH_H
#define MESH_H
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
#include <stdexcept>
#include <d3d11_1.h>
#include <DirectXMath.h>
using namespace DirectX;
#include "SafeRelease.hpp"
struct VERTEX {
FLOAT X, Y, Z;
XMFLOAT2 texcoord;
};
struct Texture {
std::string type;
std::string path;
ID3D11ShaderResourceView *texture;
void Release() {
SafeRelease(texture);
}
};
class Mesh {
public:
std::vector<VERTEX> vertices_;
std::vector<UINT> indices_;
std::vector<Texture> textures_;
ID3D11Device *dev_;
Mesh(ID3D11Device *dev, const std::vector<VERTEX>& vertices, const std::vector<UINT>& indices, const std::vector<Texture>& textures) :
vertices_(vertices),
indices_(indices),
textures_(textures),
dev_(dev),
VertexBuffer_(nullptr),
IndexBuffer_(nullptr) {
this->setupMesh(this->dev_);
}
void Draw(ID3D11DeviceContext *devcon) {
UINT stride = sizeof(VERTEX);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &VertexBuffer_, &stride, &offset);
devcon->IASetIndexBuffer(IndexBuffer_, DXGI_FORMAT_R32_UINT, 0);
devcon->PSSetShaderResources(0, 1, &textures_[0].texture);
devcon->DrawIndexed(static_cast<UINT>(indices_.size()), 0, 0);
}
void Close() {
SafeRelease(VertexBuffer_);
SafeRelease(IndexBuffer_);
}
private:
// Render data
ID3D11Buffer *VertexBuffer_, *IndexBuffer_;
// Functions
// Initializes all the buffer objects/arrays
void setupMesh(ID3D11Device *dev) {
HRESULT hr;
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = static_cast<UINT>(sizeof(VERTEX) * vertices_.size());
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = &vertices_[0];
hr = dev->CreateBuffer(&vbd, &initData, &VertexBuffer_);
if (FAILED(hr)) {
Close();
throw std::runtime_error("Failed to create vertex buffer.");
}
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = static_cast<UINT>(sizeof(UINT) * indices_.size());
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
initData.pSysMem = &indices_[0];
hr = dev->CreateBuffer(&ibd, &initData, &IndexBuffer_);
if (FAILED(hr)) {
Close();
throw std::runtime_error("Failed to create index buffer.");
}
}
};
#endif

View file

@ -0,0 +1,186 @@
#include "ModelLoader.h"
ModelLoader::ModelLoader() :
dev_(nullptr),
devcon_(nullptr),
meshes_(),
directory_(),
textures_loaded_(),
hwnd_(nullptr) {
// empty
}
ModelLoader::~ModelLoader() {
// empty
}
bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devcon, std::string filename) {
Assimp::Importer importer;
const aiScene* pScene = importer.ReadFile(filename,
aiProcess_Triangulate |
aiProcess_ConvertToLeftHanded);
if (pScene == nullptr)
return false;
this->directory_ = filename.substr(0, filename.find_last_of("/\\"));
this->dev_ = dev;
this->devcon_ = devcon;
this->hwnd_ = hwnd;
processNode(pScene->mRootNode, pScene);
return true;
}
void ModelLoader::Draw(ID3D11DeviceContext * devcon) {
for (size_t i = 0; i < meshes_.size(); ++i ) {
meshes_[i].Draw(devcon);
}
}
Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) {
// Data to fill
std::vector<VERTEX> vertices;
std::vector<UINT> indices;
std::vector<Texture> textures;
// Walk through each of the mesh's vertices
for (UINT i = 0; i < mesh->mNumVertices; i++) {
VERTEX vertex;
vertex.X = mesh->mVertices[i].x;
vertex.Y = mesh->mVertices[i].y;
vertex.Z = mesh->mVertices[i].z;
if (mesh->mTextureCoords[0]) {
vertex.texcoord.x = (float)mesh->mTextureCoords[0][i].x;
vertex.texcoord.y = (float)mesh->mTextureCoords[0][i].y;
}
vertices.push_back(vertex);
}
for (UINT i = 0; i < mesh->mNumFaces; i++) {
aiFace face = mesh->mFaces[i];
for (UINT j = 0; j < face.mNumIndices; j++)
indices.push_back(face.mIndices[j]);
}
if (mesh->mMaterialIndex >= 0) {
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
std::vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse", scene);
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
}
return Mesh(dev_, vertices, indices, textures);
}
std::vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureType type, std::string typeName, const aiScene * scene) {
std::vector<Texture> textures;
for (UINT i = 0; i < mat->GetTextureCount(type); i++) {
aiString str;
mat->GetTexture(type, i, &str);
// Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture
bool skip = false;
for (UINT j = 0; j < textures_loaded_.size(); j++) {
if (std::strcmp(textures_loaded_[j].path.c_str(), str.C_Str()) == 0) {
textures.push_back(textures_loaded_[j]);
skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization)
break;
}
}
if (!skip) { // If texture hasn't been loaded already, load it
HRESULT hr;
Texture texture;
const aiTexture* embeddedTexture = scene->GetEmbeddedTexture(str.C_Str());
if (embeddedTexture != nullptr) {
texture.texture = loadEmbeddedTexture(embeddedTexture);
} else {
std::string filename = std::string(str.C_Str());
filename = directory_ + '/' + filename;
std::wstring filenamews = std::wstring(filename.begin(), filename.end());
hr = CreateWICTextureFromFile(dev_, devcon_, filenamews.c_str(), nullptr, &texture.texture);
if (FAILED(hr))
MessageBox(hwnd_, "Texture couldn't be loaded", "Error!", MB_ICONERROR | MB_OK);
}
texture.type = typeName;
texture.path = str.C_Str();
textures.push_back(texture);
this->textures_loaded_.push_back(texture); // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.
}
}
return textures;
}
void ModelLoader::Close() {
for (auto& t : textures_loaded_)
t.Release();
for (size_t i = 0; i < meshes_.size(); i++) {
meshes_[i].Close();
}
}
void ModelLoader::processNode(aiNode * node, const aiScene * scene) {
for (UINT i = 0; i < node->mNumMeshes; i++) {
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
meshes_.push_back(this->processMesh(mesh, scene));
}
for (UINT i = 0; i < node->mNumChildren; i++) {
this->processNode(node->mChildren[i], scene);
}
}
ID3D11ShaderResourceView * ModelLoader::loadEmbeddedTexture(const aiTexture* embeddedTexture) {
HRESULT hr;
ID3D11ShaderResourceView *texture = nullptr;
if (embeddedTexture->mHeight != 0) {
// Load an uncompressed ARGB8888 embedded texture
D3D11_TEXTURE2D_DESC desc;
desc.Width = embeddedTexture->mWidth;
desc.Height = embeddedTexture->mHeight;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA subresourceData;
subresourceData.pSysMem = embeddedTexture->pcData;
subresourceData.SysMemPitch = embeddedTexture->mWidth * 4;
subresourceData.SysMemSlicePitch = embeddedTexture->mWidth * embeddedTexture->mHeight * 4;
ID3D11Texture2D *texture2D = nullptr;
hr = dev_->CreateTexture2D(&desc, &subresourceData, &texture2D);
if (FAILED(hr))
MessageBox(hwnd_, "CreateTexture2D failed!", "Error!", MB_ICONERROR | MB_OK);
hr = dev_->CreateShaderResourceView(texture2D, nullptr, &texture);
if (FAILED(hr))
MessageBox(hwnd_, "CreateShaderResourceView failed!", "Error!", MB_ICONERROR | MB_OK);
return texture;
}
// mHeight is 0, so try to load a compressed texture of mWidth bytes
const size_t size = embeddedTexture->mWidth;
hr = CreateWICTextureFromMemory(dev_, devcon_, reinterpret_cast<const unsigned char*>(embeddedTexture->pcData), size, nullptr, &texture);
if (FAILED(hr))
MessageBox(hwnd_, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK);
return texture;
}

View file

@ -0,0 +1,42 @@
#ifndef MODEL_LOADER_H
#define MODEL_LOADER_H
#include <vector>
#include <d3d11_1.h>
#include <DirectXMath.h>
#include <assimp\Importer.hpp>
#include <assimp\scene.h>
#include <assimp\postprocess.h>
#include "Mesh.h"
#include "TextureLoader.h"
using namespace DirectX;
class ModelLoader
{
public:
ModelLoader();
~ModelLoader();
bool Load(HWND hwnd, ID3D11Device* dev, ID3D11DeviceContext* devcon, std::string filename);
void Draw(ID3D11DeviceContext* devcon);
void Close();
private:
ID3D11Device *dev_;
ID3D11DeviceContext *devcon_;
std::vector<Mesh> meshes_;
std::string directory_;
std::vector<Texture> textures_loaded_;
HWND hwnd_;
void processNode(aiNode* node, const aiScene* scene);
Mesh processMesh(aiMesh* mesh, const aiScene* scene);
std::vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName, const aiScene* scene);
ID3D11ShaderResourceView* loadEmbeddedTexture(const aiTexture* embeddedTexture);
};
#endif // !MODEL_LOADER_H

View file

@ -0,0 +1,9 @@
Texture2D diffTexture;
SamplerState SampleType;
float4 main(float4 pos : SV_POSITION, float2 texcoord : TEXCOORD) : SV_TARGET
{
float4 textureColor = diffTexture.Sample(SampleType, texcoord);
return textureColor;
}

View file

@ -0,0 +1,57 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifdef _MSC_VER
#pragma once
#endif
/* Used to reduce to reduce the number of lines when calling Release()
on a D3D interface. Implemented as a template instead of a 'SAFE_RELEASE'
MACRO to ease debugging. */
template<typename T>
inline void SafeRelease(T*& x) {
if (x) {
x->Release();
x = nullptr;
}
}

View file

@ -0,0 +1,697 @@
//--------------------------------------------------------------------------------------
// File: WICTextureLoader.cpp
//
// Function for loading a WIC image and creating a Direct3D 11 runtime texture for it
// (auto-generating mipmaps if possible)
//
// Note: Assumes application has already called CoInitializeEx
//
// Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for
// auto-gen mipmap support.
//
// Note these functions are useful for images created as simple 2D textures. For
// more complex resources, DDSTextureLoader is an excellent light-weight runtime loader.
// For a full-featured DDS file reader, writer, and texture processing pipeline see
// the 'Texconv' sample and the 'DirectXTex' library.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=248926
// http://go.microsoft.com/fwlink/?LinkId=248929
//--------------------------------------------------------------------------------------
// We could load multi-frame images (TIFF/GIF) into a texture array.
// For now, we just load the first frame (note: DirectXTex supports multi-frame images)
#include <dxgiformat.h>
#include <assert.h>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4005)
#endif // _MSC_VER
#include <wincodec.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER
#include <memory>
#include "TextureLoader.h"
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) && !defined(DXGI_1_2_FORMATS)
#define DXGI_1_2_FORMATS
#endif
//---------------------------------------------------------------------------------
template<class T> class ScopedObject
{
public:
explicit ScopedObject(T *p = 0) : _pointer(p) {}
~ScopedObject()
{
if (_pointer)
{
_pointer->Release();
_pointer = nullptr;
}
}
bool IsNull() const { return (!_pointer); }
T& operator*() { return *_pointer; }
T* operator->() { return _pointer; }
T** operator&() { return &_pointer; }
void Reset(T *p = 0) { if (_pointer) { _pointer->Release(); } _pointer = p; }
T* Get() const { return _pointer; }
private:
ScopedObject(const ScopedObject&);
ScopedObject& operator=(const ScopedObject&);
T* _pointer;
};
//-------------------------------------------------------------------------------------
// WIC Pixel Format Translation Data
//-------------------------------------------------------------------------------------
struct WICTranslate
{
GUID wic;
DXGI_FORMAT format;
};
static WICTranslate g_WICFormats[] =
{
{ GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT },
{ GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT },
{ GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM },
{ GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM },
{ GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM }, // DXGI 1.1
{ GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM }, // DXGI 1.1
{ GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, // DXGI 1.1
{ GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM },
{ GUID_WICPixelFormat32bppRGBE, DXGI_FORMAT_R9G9B9E5_SHAREDEXP },
#ifdef DXGI_1_2_FORMATS
{ GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM },
{ GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM },
#endif // DXGI_1_2_FORMATS
{ GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT },
{ GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT },
{ GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM },
{ GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM },
{ GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM },
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
{ GUID_WICPixelFormat96bppRGBFloat, DXGI_FORMAT_R32G32B32_FLOAT },
#endif
};
//-------------------------------------------------------------------------------------
// WIC Pixel Format nearest conversion table
//-------------------------------------------------------------------------------------
struct WICConvert
{
GUID source;
GUID target;
};
static WICConvert g_WICConvert[] =
{
// Note target GUID in this conversion table must be one of those directly supported formats (above).
{ GUID_WICPixelFormatBlackWhite, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
{ GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
{ GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
{ GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT
{ GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT
#ifdef DXGI_1_2_FORMATS
{ GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM
#else
{ GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat16bppBGRA5551, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat16bppBGR565, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
#endif // DXGI_1_2_FORMATS
{ GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM
{ GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat96bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
{ GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
#endif
// We don't support n-channel formats
};
//--------------------------------------------------------------------------------------
static IWICImagingFactory* _GetWIC()
{
static IWICImagingFactory* s_Factory = nullptr;
if (s_Factory)
return s_Factory;
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
(LPVOID*)&s_Factory
);
if (FAILED(hr))
{
s_Factory = nullptr;
return nullptr;
}
return s_Factory;
}
//---------------------------------------------------------------------------------
static DXGI_FORMAT _WICToDXGI(const GUID& guid)
{
for (size_t i = 0; i < _countof(g_WICFormats); ++i)
{
if (memcmp(&g_WICFormats[i].wic, &guid, sizeof(GUID)) == 0)
return g_WICFormats[i].format;
}
return DXGI_FORMAT_UNKNOWN;
}
//---------------------------------------------------------------------------------
static size_t _WICBitsPerPixel(REFGUID targetGuid)
{
IWICImagingFactory* pWIC = _GetWIC();
if (!pWIC)
return 0;
ScopedObject<IWICComponentInfo> cinfo;
if (FAILED(pWIC->CreateComponentInfo(targetGuid, &cinfo)))
return 0;
WICComponentType type;
if (FAILED(cinfo->GetComponentType(&type)))
return 0;
if (type != WICPixelFormat)
return 0;
ScopedObject<IWICPixelFormatInfo> pfinfo;
if (FAILED(cinfo->QueryInterface(__uuidof(IWICPixelFormatInfo), reinterpret_cast<void**>(&pfinfo))))
return 0;
UINT bpp;
if (FAILED(pfinfo->GetBitsPerPixel(&bpp)))
return 0;
return bpp;
}
//---------------------------------------------------------------------------------
static HRESULT CreateTextureFromWIC(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_ IWICBitmapFrameDecode *frame,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize)
{
UINT width, height;
HRESULT hr = frame->GetSize(&width, &height);
if (FAILED(hr))
return hr;
assert(width > 0 && height > 0);
if (!maxsize)
{
// This is a bit conservative because the hardware could support larger textures than
// the Feature Level defined minimums, but doing it this way is much easier and more
// performant for WIC than the 'fail and retry' model used by DDSTextureLoader
switch (d3dDevice->GetFeatureLevel())
{
case D3D_FEATURE_LEVEL_9_1:
case D3D_FEATURE_LEVEL_9_2:
maxsize = 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
break;
case D3D_FEATURE_LEVEL_9_3:
maxsize = 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
break;
case D3D_FEATURE_LEVEL_10_0:
case D3D_FEATURE_LEVEL_10_1:
maxsize = 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
break;
default:
maxsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
break;
}
}
assert(maxsize > 0);
UINT twidth, theight;
if (width > maxsize || height > maxsize)
{
float ar = static_cast<float>(height) / static_cast<float>(width);
if (width > height)
{
twidth = static_cast<UINT>(maxsize);
theight = static_cast<UINT>(static_cast<float>(maxsize) * ar);
}
else
{
theight = static_cast<UINT>(maxsize);
twidth = static_cast<UINT>(static_cast<float>(maxsize) / ar);
}
assert(twidth <= maxsize && theight <= maxsize);
}
else
{
twidth = width;
theight = height;
}
// Determine format
WICPixelFormatGUID pixelFormat;
hr = frame->GetPixelFormat(&pixelFormat);
if (FAILED(hr))
return hr;
WICPixelFormatGUID convertGUID;
memcpy(&convertGUID, &pixelFormat, sizeof(WICPixelFormatGUID));
size_t bpp = 0;
DXGI_FORMAT format = _WICToDXGI(pixelFormat);
if (format == DXGI_FORMAT_UNKNOWN)
{
for (size_t i = 0; i < _countof(g_WICConvert); ++i)
{
if (memcmp(&g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID)) == 0)
{
memcpy(&convertGUID, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID));
format = _WICToDXGI(g_WICConvert[i].target);
assert(format != DXGI_FORMAT_UNKNOWN);
bpp = _WICBitsPerPixel(convertGUID);
break;
}
}
if (format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
else
{
bpp = _WICBitsPerPixel(pixelFormat);
}
if (!bpp)
return E_FAIL;
// Verify our target format is supported by the current device
// (handles WDDM 1.0 or WDDM 1.1 device driver cases as well as DirectX 11.0 Runtime without 16bpp format support)
UINT support = 0;
hr = d3dDevice->CheckFormatSupport(format, &support);
if (FAILED(hr) || !(support & D3D11_FORMAT_SUPPORT_TEXTURE2D))
{
// Fallback to RGBA 32-bit format which is supported by all devices
memcpy(&convertGUID, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID));
format = DXGI_FORMAT_R8G8B8A8_UNORM;
bpp = 32;
}
// Allocate temporary memory for image
size_t rowPitch = (twidth * bpp + 7) / 8;
size_t imageSize = rowPitch * theight;
std::unique_ptr<uint8_t[]> temp(new uint8_t[imageSize]);
// Load image data
if (memcmp(&convertGUID, &pixelFormat, sizeof(GUID)) == 0
&& twidth == width
&& theight == height)
{
// No format conversion or resize needed
hr = frame->CopyPixels(0, static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize), temp.get());
if (FAILED(hr))
return hr;
}
else if (twidth != width || theight != height)
{
// Resize
IWICImagingFactory* pWIC = _GetWIC();
if (!pWIC)
return E_NOINTERFACE;
ScopedObject<IWICBitmapScaler> scaler;
hr = pWIC->CreateBitmapScaler(&scaler);
if (FAILED(hr))
return hr;
hr = scaler->Initialize(frame, twidth, theight, WICBitmapInterpolationModeFant);
if (FAILED(hr))
return hr;
WICPixelFormatGUID pfScaler;
hr = scaler->GetPixelFormat(&pfScaler);
if (FAILED(hr))
return hr;
if (memcmp(&convertGUID, &pfScaler, sizeof(GUID)) == 0)
{
// No format conversion needed
hr = scaler->CopyPixels(0, static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize), temp.get());
if (FAILED(hr))
return hr;
}
else
{
ScopedObject<IWICFormatConverter> FC;
hr = pWIC->CreateFormatConverter(&FC);
if (FAILED(hr))
return hr;
hr = FC->Initialize(scaler.Get(), convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom);
if (FAILED(hr))
return hr;
hr = FC->CopyPixels(0, static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize), temp.get());
if (FAILED(hr))
return hr;
}
}
else
{
// Format conversion but no resize
IWICImagingFactory* pWIC = _GetWIC();
if (!pWIC)
return E_NOINTERFACE;
ScopedObject<IWICFormatConverter> FC;
hr = pWIC->CreateFormatConverter(&FC);
if (FAILED(hr))
return hr;
hr = FC->Initialize(frame, convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom);
if (FAILED(hr))
return hr;
hr = FC->CopyPixels(0, static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize), temp.get());
if (FAILED(hr))
return hr;
}
// See if format is supported for auto-gen mipmaps (varies by feature level)
bool autogen = false;
if (d3dContext != 0 && textureView != 0) // Must have context and shader-view to auto generate mipmaps
{
UINT fmtSupport = 0;
hr = d3dDevice->CheckFormatSupport(format, &fmtSupport);
if (SUCCEEDED(hr) && (fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN))
{
autogen = true;
}
}
// Create texture
D3D11_TEXTURE2D_DESC desc;
desc.Width = twidth;
desc.Height = theight;
desc.MipLevels = (autogen) ? 0 : 1;
desc.ArraySize = 1;
desc.Format = format;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = (autogen) ? (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) : (D3D11_BIND_SHADER_RESOURCE);
desc.CPUAccessFlags = 0;
desc.MiscFlags = (autogen) ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = temp.get();
initData.SysMemPitch = static_cast<UINT>(rowPitch);
initData.SysMemSlicePitch = static_cast<UINT>(imageSize);
ID3D11Texture2D* tex = nullptr;
hr = d3dDevice->CreateTexture2D(&desc, (autogen) ? nullptr : &initData, &tex);
if (SUCCEEDED(hr) && tex != 0)
{
if (textureView != 0)
{
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
memset(&SRVDesc, 0, sizeof(SRVDesc));
SRVDesc.Format = format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1;
hr = d3dDevice->CreateShaderResourceView(tex, &SRVDesc, textureView);
if (FAILED(hr))
{
tex->Release();
return hr;
}
if (autogen)
{
assert(d3dContext != 0);
d3dContext->UpdateSubresource(tex, 0, nullptr, temp.get(), static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize));
d3dContext->GenerateMips(*textureView);
}
}
if (texture != 0)
{
*texture = tex;
}
else
{
#if defined(_DEBUG) || defined(PROFILE)
tex->SetPrivateData(WKPDID_D3DDebugObjectName,
sizeof("WICTextureLoader") - 1,
"WICTextureLoader"
);
#endif
tex->Release();
}
}
return hr;
}
//--------------------------------------------------------------------------------------
HRESULT CreateWICTextureFromMemory(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_bytecount_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize
)
{
if (!d3dDevice || !wicData || (!texture && !textureView))
{
return E_INVALIDARG;
}
if (!wicDataSize)
{
return E_FAIL;
}
#ifdef _M_AMD64
if (wicDataSize > 0xFFFFFFFF)
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
#endif
IWICImagingFactory* pWIC = _GetWIC();
if (!pWIC)
return E_NOINTERFACE;
// Create input stream for memory
ScopedObject<IWICStream> stream;
HRESULT hr = pWIC->CreateStream(&stream);
if (FAILED(hr))
return hr;
hr = stream->InitializeFromMemory(const_cast<uint8_t*>(wicData), static_cast<DWORD>(wicDataSize));
if (FAILED(hr))
return hr;
// Initialize WIC
ScopedObject<IWICBitmapDecoder> decoder;
hr = pWIC->CreateDecoderFromStream(stream.Get(), 0, WICDecodeMetadataCacheOnDemand, &decoder);
if (FAILED(hr))
return hr;
ScopedObject<IWICBitmapFrameDecode> frame;
hr = decoder->GetFrame(0, &frame);
if (FAILED(hr))
return hr;
hr = CreateTextureFromWIC(d3dDevice, d3dContext, frame.Get(), texture, textureView, maxsize);
if (FAILED(hr))
return hr;
#if defined(_DEBUG) || defined(PROFILE)
if (texture != 0 && *texture != 0)
{
(*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,
sizeof("WICTextureLoader") - 1,
"WICTextureLoader"
);
}
if (textureView != 0 && *textureView != 0)
{
(*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,
sizeof("WICTextureLoader") - 1,
"WICTextureLoader"
);
}
#endif
return hr;
}
//--------------------------------------------------------------------------------------
HRESULT CreateWICTextureFromFile(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_z_ const wchar_t* fileName,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize)
{
if (!d3dDevice || !fileName || (!texture && !textureView))
{
return E_INVALIDARG;
}
IWICImagingFactory* pWIC = _GetWIC();
if (!pWIC)
return E_NOINTERFACE;
// Initialize WIC
ScopedObject<IWICBitmapDecoder> decoder;
HRESULT hr = pWIC->CreateDecoderFromFilename(fileName, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &decoder);
if (FAILED(hr))
return hr;
ScopedObject<IWICBitmapFrameDecode> frame;
hr = decoder->GetFrame(0, &frame);
if (FAILED(hr))
return hr;
hr = CreateTextureFromWIC(d3dDevice, d3dContext, frame.Get(), texture, textureView, maxsize);
if (FAILED(hr))
return hr;
#if defined(_DEBUG) || defined(PROFILE)
if (texture != 0 || textureView != 0)
{
CHAR strFileA[MAX_PATH];
WideCharToMultiByte(CP_ACP,
WC_NO_BEST_FIT_CHARS,
fileName,
-1,
strFileA,
MAX_PATH,
nullptr,
FALSE
);
const CHAR* pstrName = strrchr(strFileA, '\\');
if (!pstrName)
{
pstrName = strFileA;
}
else
{
pstrName++;
}
if (texture != 0 && *texture != 0)
{
(*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
if (textureView != 0 && *textureView != 0)
{
(*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,
static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),
pstrName
);
}
}
#endif
return hr;
}

View file

@ -0,0 +1,61 @@
//--------------------------------------------------------------------------------------
// File: WICTextureLoader.h
//
// Function for loading a WIC image and creating a Direct3D 11 runtime texture for it
// (auto-generating mipmaps if possible)
//
// Note: Assumes application has already called CoInitializeEx
//
// Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for
// auto-gen mipmap support.
//
// Note these functions are useful for images created as simple 2D textures. For
// more complex resources, DDSTextureLoader is an excellent light-weight runtime loader.
// For a full-featured DDS file reader, writer, and texture processing pipeline see
// the 'Texconv' sample and the 'DirectXTex' library.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=248926
// http://go.microsoft.com/fwlink/?LinkId=248929
//--------------------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma once
#endif
#include <d3d11.h>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4005)
#endif // _MSC_VER
#include <stdint.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER
HRESULT CreateWICTextureFromMemory(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_bytecount_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0
);
HRESULT CreateWICTextureFromFile(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext,
_In_z_ const wchar_t* szFileName,
_Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0
);

View file

@ -0,0 +1,23 @@
cbuffer ConstantBuffer : register(b0)
{
matrix World;
matrix View;
matrix Projection;
}
struct VOut {
float4 pos : SV_POSITION;
float2 texcoord : TEXCOORD;
};
VOut main(float4 pos : POSITION, float2 texcoord : TEXCOORD)
{
VOut output;
output.pos = mul(pos, World);
output.pos = mul(output.pos, View);
output.pos = mul(output.pos, Projection);
output.texcoord = texcoord;
return output;
}

View file

@ -0,0 +1,599 @@
// ---------------------------------------------------------------------------
// Simple Assimp Directx11 Sample
// This is a very basic sample and only reads diffuse texture
// but this can load both embedded textures in fbx and non-embedded textures
//
//
// Replace ourModel->Load(hwnd, dev, devcon, "Models/myModel.fbx") this with your
// model name (line 480)
// If your model isn't a fbx with embedded textures make sure your model's
// textures are in same directory as your model
//
//
// Written by IAS. :)
// ---------------------------------------------------------------------------
#include <Windows.h>
#include <shellapi.h>
#include <stdexcept>
#include <windowsx.h>
#include <d3d11_1.h>
#include <dxgi1_2.h>
#include <DirectXMath.h>
#include <d3dcompiler.h>
#include "ModelLoader.h"
#include "UTFConverter.h"
#include "SafeRelease.hpp"
#ifdef _MSC_VER
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "Dxgi.lib")
#pragma comment(lib,"d3dcompiler.lib")
#pragma comment (lib, "dxguid.lib")
#endif // _MSC_VER
using namespace DirectX;
using namespace AssimpSamples::SharedCode;
#define VERTEX_SHADER_FILE L"VertexShader.hlsl"
#define PIXEL_SHADER_FILE L"PixelShader.hlsl"
// ------------------------------------------------------------
// Structs
// ------------------------------------------------------------
struct ConstantBuffer {
XMMATRIX mWorld;
XMMATRIX mView;
XMMATRIX mProjection;
};
// ------------------------------------------------------------
// Window Variables
// ------------------------------------------------------------
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
const char g_szClassName[] = "directxWindowClass";
static std::string g_ModelPath;
UINT width, height;
HWND g_hwnd = nullptr;
// ------------------------------------------------------------
// DirectX Variables
// ------------------------------------------------------------
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device *dev = nullptr;
ID3D11Device1 *dev1 = nullptr;
ID3D11DeviceContext *devcon = nullptr;
ID3D11DeviceContext1 *devcon1 = nullptr;
IDXGISwapChain *swapchain = nullptr;
IDXGISwapChain1 *swapchain1 = nullptr;
ID3D11RenderTargetView *backbuffer = nullptr;
ID3D11VertexShader *pVS = nullptr;
ID3D11PixelShader *pPS = nullptr;
ID3D11InputLayout *pLayout = nullptr;
ID3D11Buffer *pConstantBuffer = nullptr;
ID3D11Texture2D *g_pDepthStencil = nullptr;
ID3D11DepthStencilView *g_pDepthStencilView = nullptr;
ID3D11SamplerState *TexSamplerState = nullptr;
ID3D11RasterizerState *rasterstate = nullptr;
ID3D11Debug* d3d11debug = nullptr;
XMMATRIX m_World;
XMMATRIX m_View;
XMMATRIX m_Projection;
// ------------------------------------------------------------
// Function identifiers
// ------------------------------------------------------------
void InitD3D(HINSTANCE hinstance, HWND hWnd);
void CleanD3D(void);
void RenderFrame(void);
void InitPipeline();
void InitGraphics();
HRESULT CompileShaderFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefines, LPCSTR pEntryPoint, LPCSTR pShaderModel, ID3DBlob** ppBytecodeBlob);
void Throwanerror(LPCSTR errormessage);
// ------------------------------------------------------------
// Our Model
// ------------------------------------------------------------
ModelLoader *ourModel = nullptr;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
LPWSTR /*lpCmdLine*/, int nCmdShow)
{
int argc;
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if (!argv) {
MessageBox(nullptr,
TEXT("An error occurred while reading command line arguments."),
TEXT("Error!"),
MB_ICONERROR | MB_OK);
return EXIT_FAILURE;
}
// Free memory allocated from CommandLineToArgvW.
auto free_command_line_allocated_memory = [&argv]() {
if (argv) {
LocalFree(argv);
argv = nullptr;
}
};
// Ensure that a model file has been specified.
if (argc < 2) {
MessageBox(nullptr,
TEXT("No model file specified. The program will now close."),
TEXT("Error!"),
MB_ICONERROR | MB_OK);
free_command_line_allocated_memory();
return EXIT_FAILURE;
}
// Retrieve the model file path.
g_ModelPath = UTFConverter(argv[1]).str();
free_command_line_allocated_memory();
WNDCLASSEX wc;
MSG msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(nullptr, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
RECT wr = { 0,0, SCREEN_WIDTH, SCREEN_HEIGHT };
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
g_hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
" Simple Textured Directx11 Sample ",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top,
nullptr, nullptr, hInstance, nullptr
);
if (g_hwnd == nullptr)
{
MessageBox(nullptr, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(g_hwnd, nCmdShow);
UpdateWindow(g_hwnd);
width = wr.right - wr.left;
height = wr.bottom - wr.top;
try {
InitD3D(hInstance, g_hwnd);
while (true)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT)
break;
}
RenderFrame();
}
CleanD3D();
return static_cast<int>(msg.wParam);
} catch (const std::exception& e) {
MessageBox(g_hwnd, e.what(), TEXT("Error!"), MB_ICONERROR | MB_OK);
CleanD3D();
return EXIT_FAILURE;
} catch (...) {
MessageBox(g_hwnd, TEXT("Caught an unknown exception."), TEXT("Error!"), MB_ICONERROR | MB_OK);
CleanD3D();
return EXIT_FAILURE;
}
}
void InitD3D(HINSTANCE /*hinstance*/, HWND hWnd)
{
HRESULT hr;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDevice(nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &dev, &g_featureLevel, &devcon);
if (hr == E_INVALIDARG)
{
// DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
hr = D3D11CreateDevice(nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
D3D11_SDK_VERSION, &dev, &g_featureLevel, &devcon);
}
if (SUCCEEDED(hr))
break;
}
if (FAILED(hr))
Throwanerror("Directx Device Creation Failed!");
#if _DEBUG
hr = dev->QueryInterface(IID_PPV_ARGS(&d3d11debug));
if (FAILED(hr))
OutputDebugString(TEXT("Failed to retrieve DirectX 11 debug interface.\n"));
#endif
UINT m4xMsaaQuality;
dev->CheckMultisampleQualityLevels(
DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
// Obtain DXGI factory from device (since we used nullptr for pAdapter above)
IDXGIFactory1* dxgiFactory = nullptr;
{
IDXGIDevice* dxgiDevice = nullptr;
hr = dev->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
if (SUCCEEDED(hr))
{
IDXGIAdapter* adapter = nullptr;
hr = dxgiDevice->GetAdapter(&adapter);
if (SUCCEEDED(hr))
{
hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory));
adapter->Release();
}
dxgiDevice->Release();
}
}
if (FAILED(hr))
Throwanerror("DXGI Factory couldn't be obtained!");
// Create swap chain
IDXGIFactory2* dxgiFactory2 = nullptr;
hr = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2));
if (dxgiFactory2)
{
// DirectX 11.1 or later
hr = dev->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&dev1));
if (SUCCEEDED(hr))
{
(void)devcon->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&devcon1));
}
DXGI_SWAP_CHAIN_DESC1 sd;
ZeroMemory(&sd, sizeof(sd));
sd.Width = SCREEN_WIDTH;
sd.Height = SCREEN_HEIGHT;
sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.SampleDesc.Count = 4;
sd.SampleDesc.Quality = m4xMsaaQuality - 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
hr = dxgiFactory2->CreateSwapChainForHwnd(dev, hWnd, &sd, nullptr, nullptr, &swapchain1);
if (SUCCEEDED(hr))
{
hr = swapchain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&swapchain));
}
dxgiFactory2->Release();
}
else
{
// DirectX 11.0 systems
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = SCREEN_WIDTH;
sd.BufferDesc.Height = SCREEN_HEIGHT;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = m4xMsaaQuality - 1;
sd.Windowed = TRUE;
hr = dxgiFactory->CreateSwapChain(dev, &sd, &swapchain);
}
// Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut
dxgiFactory->MakeWindowAssociation(g_hwnd, DXGI_MWA_NO_ALT_ENTER);
dxgiFactory->Release();
if (FAILED(hr))
Throwanerror("Swapchain Creation Failed!");
ID3D11Texture2D *pBackBuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
dev->CreateRenderTargetView(pBackBuffer, nullptr, &backbuffer);
pBackBuffer->Release();
D3D11_TEXTURE2D_DESC descDepth;
ZeroMemory(&descDepth, sizeof(descDepth));
descDepth.Width = SCREEN_WIDTH;
descDepth.Height = SCREEN_HEIGHT;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
descDepth.SampleDesc.Count = 4;
descDepth.SampleDesc.Quality = m4xMsaaQuality - 1;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
hr = dev->CreateTexture2D(&descDepth, nullptr, &g_pDepthStencil);
if (FAILED(hr))
Throwanerror("Depth Stencil Texture couldn't be created!");
// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
ZeroMemory(&descDSV, sizeof(descDSV));
descDSV.Format = descDepth.Format;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
hr = dev->CreateDepthStencilView(g_pDepthStencil, 0, &g_pDepthStencilView);
if (FAILED(hr))
{
Throwanerror("Depth Stencil View couldn't be created!");
}
devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView);
D3D11_RASTERIZER_DESC rasterDesc;
rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_BACK;
rasterDesc.DepthBias = 0;
rasterDesc.DepthBiasClamp = 0.0f;
rasterDesc.DepthClipEnable = true;
rasterDesc.FillMode = D3D11_FILL_SOLID;
rasterDesc.FrontCounterClockwise = false;
rasterDesc.MultisampleEnable = false;
rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;
dev->CreateRasterizerState(&rasterDesc, &rasterstate);
devcon->RSSetState(rasterstate);
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.Width = SCREEN_WIDTH;
viewport.Height = SCREEN_HEIGHT;
devcon->RSSetViewports(1, &viewport);
InitPipeline();
InitGraphics();
}
void CleanD3D(void)
{
if (swapchain)
swapchain->SetFullscreenState(FALSE, nullptr);
if (ourModel) {
ourModel->Close();
delete ourModel;
ourModel = nullptr;
}
SafeRelease(TexSamplerState);
SafeRelease(pConstantBuffer);
SafeRelease(pLayout);
SafeRelease(pVS);
SafeRelease(pPS);
SafeRelease(rasterstate);
SafeRelease(g_pDepthStencilView);
SafeRelease(g_pDepthStencil);
SafeRelease(backbuffer);
SafeRelease(swapchain);
SafeRelease(swapchain1);
SafeRelease(devcon1);
SafeRelease(dev1);
SafeRelease(devcon);
#if _DEBUG
if (d3d11debug) {
OutputDebugString(TEXT("Dumping DirectX 11 live objects.\n"));
d3d11debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
SafeRelease(d3d11debug);
} else {
OutputDebugString(TEXT("Unable to dump live objects: no DirectX 11 debug interface available.\n"));
}
#endif
SafeRelease(dev);
}
void RenderFrame(void)
{
static float t = 0.0f;
static ULONGLONG timeStart = 0;
ULONGLONG timeCur = GetTickCount64();
if (timeStart == 0)
timeStart = timeCur;
t = (timeCur - timeStart) / 1000.0f;
float clearColor[4] = { 0.0f, 0.2f, 0.4f, 1.0f };
devcon->ClearRenderTargetView(backbuffer, clearColor);
devcon->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_World = XMMatrixRotationY(-t);
ConstantBuffer cb;
cb.mWorld = XMMatrixTranspose(m_World);
cb.mView = XMMatrixTranspose(m_View);
cb.mProjection = XMMatrixTranspose(m_Projection);
devcon->UpdateSubresource(pConstantBuffer, 0, nullptr, &cb, 0, 0);
devcon->VSSetShader(pVS, 0, 0);
devcon->VSSetConstantBuffers(0, 1, &pConstantBuffer);
devcon->PSSetShader(pPS, 0, 0);
devcon->PSSetSamplers(0, 1, &TexSamplerState);
ourModel->Draw(devcon);
swapchain->Present(0, 0);
}
void InitPipeline()
{
ID3DBlob *VS, *PS;
if(FAILED(CompileShaderFromFile(SHADER_PATH VERTEX_SHADER_FILE, 0, "main", "vs_4_0", &VS)))
Throwanerror(UTFConverter(L"Failed to compile shader from file " VERTEX_SHADER_FILE).c_str());
if(FAILED(CompileShaderFromFile(SHADER_PATH PIXEL_SHADER_FILE, 0, "main", "ps_4_0", &PS)))
Throwanerror(UTFConverter(L"Failed to compile shader from file " PIXEL_SHADER_FILE).c_str());
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), nullptr, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), nullptr, &pPS);
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout);
devcon->IASetInputLayout(pLayout);
}
void InitGraphics()
{
HRESULT hr;
m_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.01f, 1000.0f);
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBuffer);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = dev->CreateBuffer(&bd, nullptr, &pConstantBuffer);
if (FAILED(hr))
Throwanerror("Constant buffer couldn't be created");
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
hr = dev->CreateSamplerState(&sampDesc, &TexSamplerState);
if (FAILED(hr))
Throwanerror("Texture sampler state couldn't be created");
XMVECTOR Eye = XMVectorSet(0.0f, 5.0f, -300.0f, 0.0f);
XMVECTOR At = XMVectorSet(0.0f, 100.0f, 0.0f, 0.0f);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
m_View = XMMatrixLookAtLH(Eye, At, Up);
ourModel = new ModelLoader;
if (!ourModel->Load(g_hwnd, dev, devcon, g_ModelPath))
Throwanerror("Model couldn't be loaded");
}
HRESULT CompileShaderFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefines, LPCSTR pEntryPoint, LPCSTR pShaderModel, ID3DBlob** ppBytecodeBlob)
{
UINT compileFlags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR;
#ifdef _DEBUG
compileFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* pErrorBlob = nullptr;
HRESULT result = D3DCompileFromFile(pFileName, pDefines, D3D_COMPILE_STANDARD_FILE_INCLUDE, pEntryPoint, pShaderModel, compileFlags, 0, ppBytecodeBlob, &pErrorBlob);
if (FAILED(result))
{
if (pErrorBlob != nullptr)
OutputDebugStringA((LPCSTR)pErrorBlob->GetBufferPointer());
}
if (pErrorBlob != nullptr)
pErrorBlob->Release();
return result;
}
void Throwanerror(LPCSTR errormessage)
{
throw std::runtime_error(errormessage);
}

View file

@ -0,0 +1,50 @@
FIND_PACKAGE(OpenGL)
FIND_PACKAGE(GLUT)
IF ( NOT GLUT_FOUND )
IF ( MSVC )
SET ( GLUT_FOUND 1 )
SET ( GLUT_INCLUDE_DIR ${Assimp_SOURCE_DIR}/samples/freeglut/ )
SET ( GLUT_LIBRARIES ${Assimp_SOURCE_DIR}/samples/freeglut/lib/freeglut.lib )
ELSE ()
MESSAGE( WARNING "Please install glut." )
ENDIF ()
ENDIF ()
if ( MSVC )
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
endif ()
INCLUDE_DIRECTORIES(
${Assimp_SOURCE_DIR}/code
${OPENGL_INCLUDE_DIR}
${GLUT_INCLUDE_DIR}
${SAMPLES_SHARED_CODE_DIR}
)
LINK_DIRECTORIES(
${Assimp_BINARY_DIR}
${Assimp_BINARY_DIR}/lib/
)
ADD_EXECUTABLE( assimp_simpletexturedogl WIN32
SimpleTexturedOpenGL/src/model_loading.cpp
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.cpp
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.h
)
TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp_simpletexturedogl)
SET_PROPERTY(TARGET assimp_simpletexturedogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
TARGET_LINK_LIBRARIES( assimp_simpletexturedogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} )
SET_TARGET_PROPERTIES( assimp_simpletexturedogl PROPERTIES
OUTPUT_NAME assimp_simpletexturedogl
)
INSTALL( TARGETS assimp_simpletexturedogl
DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
)

View file

@ -0,0 +1,915 @@
// ----------------------------------------------------------------------------
// Another Assimp OpenGL sample including texturing.
// Note that it is very basic and will only read and apply the model's diffuse
// textures (by their material ids)
//
// Don't worry about the "Couldn't load Image: ...dwarf2.jpg" Message.
// It's caused by a bad texture reference in the model file (I guess)
//
// If you intend to _use_ this code sample in your app, do yourself a favour
// and replace immediate mode calls with VBOs ...
//
// Thanks to NeHe on whose OpenGL tutorials this one's based on! :)
// http://nehe.gamedev.net/
// ----------------------------------------------------------------------------
#include <windows.h>
#include <shellapi.h>
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glu.h>
#ifdef _MSC_VER
#pragma warning(disable: 4100) // Disable warning 'unreferenced formal parameter'
#endif // _MSC_VER
#define STB_IMAGE_IMPLEMENTATION
#include "contrib/stb/stb_image.h"
#ifdef _MSC_VER
#pragma warning(default: 4100) // Enable warning 'unreferenced formal parameter'
#endif // _MSC_VER
#include <fstream>
//to map image filenames to textureIds
#include <string.h>
#include <map>
// assimp include files. These three are usually needed.
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/LogStream.hpp>
#include "UTFConverter.h"
// The default hard-coded path. Can be overridden by supplying a path through the command line.
static std::string modelpath = "../../test/models/OBJ/spider.obj";
HGLRC hRC=nullptr; // Permanent Rendering Context
HDC hDC=nullptr; // Private GDI Device Context
HWND g_hWnd=nullptr; // Holds Window Handle
HINSTANCE g_hInstance=nullptr; // Holds The Instance Of The Application
bool keys[256]; // Array used for Keyboard Routine;
bool active=TRUE; // Window Active Flag Set To TRUE by Default
bool fullscreen=TRUE; // full-screen Flag Set To full-screen By Default
GLfloat xrot;
GLfloat yrot;
GLfloat zrot;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLboolean abortGLInit(const char*);
const char* windowTitle = "OpenGL Framework";
GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition[]= { 0.0f, 0.0f, 15.0f, 1.0f };
// the global Assimp scene object
const aiScene* g_scene = nullptr;
GLuint scene_list = 0;
aiVector3D scene_min, scene_max, scene_center;
// images / texture
std::map<std::string, GLuint*> textureIdMap; // map image filenames to textureIds
GLuint* textureIds; // pointer to texture Array
// Create an instance of the Importer class
Assimp::Importer importer;
using namespace AssimpSamples::SharedCode;
void createAILogger()
{
// Change this line to normal if you not want to analyse the import process
//Assimp::Logger::LogSeverity severity = Assimp::Logger::NORMAL;
Assimp::Logger::LogSeverity severity = Assimp::Logger::VERBOSE;
// Create a logger instance for Console Output
Assimp::DefaultLogger::create("",severity, aiDefaultLogStream_STDOUT);
// Create a logger instance for File Output (found in project folder or near .exe)
Assimp::DefaultLogger::create("assimp_log.txt",severity, aiDefaultLogStream_FILE);
// Now I am ready for logging my stuff
Assimp::DefaultLogger::get()->info("this is my info-call");
}
void destroyAILogger()
{
// Kill it after the work is done
Assimp::DefaultLogger::kill();
}
void logInfo(std::string logString)
{
// Will add message to File with "info" Tag
Assimp::DefaultLogger::get()->info(logString.c_str());
}
void logDebug(const char* logString)
{
// Will add message to File with "debug" Tag
Assimp::DefaultLogger::get()->debug(logString);
}
bool Import3DFromFile( const std::string& pFile)
{
// Check if file exists
std::ifstream fin(pFile.c_str());
if(!fin.fail())
{
fin.close();
}
else
{
MessageBox(nullptr, UTFConverter("Couldn't open file: " + pFile).c_wstr() , TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
logInfo( importer.GetErrorString());
return false;
}
g_scene = importer.ReadFile(pFile, aiProcessPreset_TargetRealtime_Quality);
// If the import failed, report it
if(!g_scene)
{
logInfo( importer.GetErrorString());
return false;
}
// Now we can access the file's contents.
logInfo("Import of scene " + pFile + " succeeded.");
// We're done. Everything will be cleaned up by the importer destructor
return true;
}
// Resize And Initialize The GL Window
void ReSizeGLScene(GLsizei width, GLsizei height)
{
// Prevent A Divide By Zero By
if (height==0)
{
// Making Height Equal One
height=1;
}
glViewport(0, 0, width, height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
std::string getBasePath(const std::string& path)
{
size_t pos = path.find_last_of("\\/");
return (std::string::npos == pos) ? "" : path.substr(0, pos + 1);
}
void freeTextureIds()
{
textureIdMap.clear(); //no need to delete pointers in it manually here. (Pointers point to textureIds deleted in next step)
if (textureIds)
{
delete[] textureIds;
textureIds = nullptr;
}
}
int LoadGLTextures(const aiScene* scene)
{
freeTextureIds();
//ILboolean success;
/* Before calling ilInit() version should be checked. */
/*if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
{
/// wrong DevIL version ///
std::string err_msg = "Wrong DevIL version. Old devil.dll in system32/SysWow64?";
char* cErr_msg = (char *) err_msg.c_str();
abortGLInit(cErr_msg);
return -1;
}*/
//ilInit(); /* Initialization of DevIL */
if (scene->HasTextures()) return 1;
//abortGLInit("Support for meshes with embedded textures is not implemented");
/* getTexture Filenames and Numb of Textures */
for (unsigned int m=0; m<scene->mNumMaterials; m++)
{
int texIndex = 0;
aiReturn texFound = AI_SUCCESS;
aiString path; // filename
while (texFound == AI_SUCCESS)
{
texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
textureIdMap[path.data] = nullptr; //fill map with textures, pointers still NULL yet
texIndex++;
}
}
const size_t numTextures = textureIdMap.size();
/* array with DevIL image IDs */
//ILuint* imageIds = NULL;
// imageIds = new ILuint[numTextures];
/* generate DevIL Image IDs */
// ilGenImages(numTextures, imageIds); /* Generation of numTextures image names */
/* create and fill array with GL texture ids */
textureIds = new GLuint[numTextures];
glGenTextures(static_cast<GLsizei>(numTextures), textureIds); /* Texture name generation */
/* get iterator */
std::map<std::string, GLuint*>::iterator itr = textureIdMap.begin();
std::string basepath = getBasePath(modelpath);
for (size_t i=0; i<numTextures; i++)
{
//save IL image ID
std::string filename = (*itr).first; // get filename
(*itr).second = &textureIds[i]; // save texture id for filename in map
itr++; // next texture
//ilBindImage(imageIds[i]); /* Binding of DevIL image name */
std::string fileloc = basepath + filename; /* Loading of image */
//success = ilLoadImage(fileloc.c_str());
int x, y, n;
unsigned char *data = stbi_load(fileloc.c_str(), &x, &y, &n, STBI_rgb_alpha);
if (nullptr != data )
{
// Convert every colour component into unsigned byte.If your image contains
// alpha channel you can replace IL_RGB with IL_RGBA
//success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
/*if (!success)
{
abortGLInit("Couldn't convert image");
return -1;
}*/
// Binding of texture name
glBindTexture(GL_TEXTURE_2D, textureIds[i]);
// redefine standard texture values
// We will use linear interpolation for magnification filter
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// We will use linear interpolation for minifying filter
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
// Texture specification
glTexImage2D(GL_TEXTURE_2D, 0, n, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);// Texture specification.
// we also want to be able to deal with odd texture dimensions
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
stbi_image_free(data);
}
else
{
/* Error occurred */
MessageBox(nullptr, UTFConverter("Couldn't load Image: " + fileloc).c_wstr(), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
}
}
// Because we have already copied image data into texture data we can release memory used by image.
// ilDeleteImages(numTextures, imageIds);
// Cleanup
//delete [] imageIds;
//imageIds = NULL;
return TRUE;
}
// All Setup For OpenGL goes here
int InitGL()
{
if (!LoadGLTextures(g_scene))
{
return FALSE;
}
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // Enables Smooth Shading
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculation
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); // Uses default lighting parameters
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_NORMALIZE);
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
glEnable(GL_LIGHT1);
return TRUE; // Initialization Went OK
}
// Can't send color down as a pointer to aiColor4D because AI colors are ABGR.
void Color4f(const aiColor4D *color)
{
glColor4f(color->r, color->g, color->b, color->a);
}
void set_float4(float f[4], float a, float b, float c, float d)
{
f[0] = a;
f[1] = b;
f[2] = c;
f[3] = d;
}
void color4_to_float4(const aiColor4D *c, float f[4])
{
f[0] = c->r;
f[1] = c->g;
f[2] = c->b;
f[3] = c->a;
}
void apply_material(const aiMaterial *mtl)
{
float c[4];
GLenum fill_mode;
int ret1, ret2;
aiColor4D diffuse;
aiColor4D specular;
aiColor4D ambient;
aiColor4D emission;
ai_real shininess, strength;
int two_sided;
int wireframe;
unsigned int max; // changed: to unsigned
int texIndex = 0;
aiString texPath; //contains filename of texture
if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))
{
//bind texture
unsigned int texId = *textureIdMap[texPath.data];
glBindTexture(GL_TEXTURE_2D, texId);
}
set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
color4_to_float4(&diffuse, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
color4_to_float4(&specular, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
color4_to_float4(&ambient, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
color4_to_float4(&emission, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);
max = 1;
ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
max = 1;
ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
else {
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
}
max = 1;
if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
fill_mode = wireframe ? GL_LINE : GL_FILL;
else
fill_mode = GL_FILL;
glPolygonMode(GL_FRONT_AND_BACK, fill_mode);
max = 1;
if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
}
void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float scale)
{
unsigned int i;
unsigned int n=0, t;
aiMatrix4x4 m = nd->mTransformation;
aiMatrix4x4 m2;
aiMatrix4x4::Scaling(aiVector3D(scale, scale, scale), m2);
m = m * m2;
// update transform
m.Transpose();
glPushMatrix();
glMultMatrixf((float*)&m);
// draw all meshes assigned to this node
for (; n < nd->mNumMeshes; ++n)
{
const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[n]];
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
if(mesh->mNormals == nullptr)
{
glDisable(GL_LIGHTING);
}
else
{
glEnable(GL_LIGHTING);
}
if(mesh->mColors[0] != nullptr)
{
glEnable(GL_COLOR_MATERIAL);
}
else
{
glDisable(GL_COLOR_MATERIAL);
}
for (t = 0; t < mesh->mNumFaces; ++t) {
const struct aiFace* face = &mesh->mFaces[t];
GLenum face_mode;
switch(face->mNumIndices)
{
case 1: face_mode = GL_POINTS; break;
case 2: face_mode = GL_LINES; break;
case 3: face_mode = GL_TRIANGLES; break;
default: face_mode = GL_POLYGON; break;
}
glBegin(face_mode);
for(i = 0; i < face->mNumIndices; i++) // go through all vertices in face
{
int vertexIndex = face->mIndices[i]; // get group index for current index
if(mesh->mColors[0] != nullptr)
Color4f(&mesh->mColors[0][vertexIndex]);
if(mesh->mNormals != nullptr)
if(mesh->HasTextureCoords(0)) //HasTextureCoords(texture_coordinates_set)
{
glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1 - mesh->mTextureCoords[0][vertexIndex].y); //mTextureCoords[channel][vertex]
}
glNormal3fv(&mesh->mNormals[vertexIndex].x);
glVertex3fv(&mesh->mVertices[vertexIndex].x);
}
glEnd();
}
}
// draw all children
for (n = 0; n < nd->mNumChildren; ++n)
{
recursive_render(sc, nd->mChildren[n], scale);
}
glPopMatrix();
}
void drawAiScene(const aiScene* scene)
{
logInfo("drawing objects");
recursive_render(scene, scene->mRootNode, 0.5);
}
int DrawGLScene() //Here's where we do all the drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset MV Matrix
glTranslatef(0.0f, -10.0f, -40.0f); // Move 40 Units And Into The Screen
glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
drawAiScene(g_scene);
//xrot+=0.3f;
yrot+=0.2f;
//zrot+=0.4f;
return TRUE; // okay
}
void KillGLWindow() // Properly Kill The Window
{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(nullptr, 0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
if (hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(nullptr, nullptr)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(nullptr, TEXT("Release Of DC And RC Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBox(nullptr, TEXT("Release Rendering Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
}
hRC = nullptr;
}
if (hDC)
{
if (!ReleaseDC(g_hWnd, hDC)) // Are We able to Release The DC?
MessageBox(nullptr, TEXT("Release Device Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
hDC = nullptr;
}
if (g_hWnd)
{
if (!DestroyWindow(g_hWnd)) // Are We Able To Destroy The Window
MessageBox(nullptr, TEXT("Could Not Release hWnd."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
g_hWnd = nullptr;
}
if (g_hInstance)
{
if (!UnregisterClass(TEXT("OpenGL"), g_hInstance)) // Are We Able To Unregister Class
MessageBox(nullptr, TEXT("Could Not Unregister Class."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
g_hInstance = nullptr;
}
}
GLboolean abortGLInit(const char* abortMessage)
{
KillGLWindow(); // Reset Display
MessageBox(nullptr, UTFConverter(abortMessage).c_wstr(), TEXT("ERROR"), MB_OK|MB_ICONEXCLAMATION);
return FALSE; // quit and return False
}
BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // Hold the result after searching for a match
WNDCLASS wc; // Window Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left = (long)0;
WindowRect.right = (long)width;
WindowRect.top = (long)0;
WindowRect.bottom = (long)height;
fullscreen = fullscreenflag;
g_hInstance = GetModuleHandle(nullptr); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = g_hInstance;
wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(nullptr, IDC_ARROW); // Load the default arrow
wc.hbrBackground= nullptr; // No Background required for OpenGL
wc.lpszMenuName = nullptr; // No Menu
wc.lpszClassName= TEXT("OpenGL"); // Class Name
if (!RegisterClass(&wc))
{
MessageBox(nullptr, TEXT("Failed to register the window class"), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
return FALSE; //exit and return false
}
if (fullscreen) // attempt fullscreen mode
{
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make Sure Memory's Cleared
dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size Of the devmode structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // bits per pixel
dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode and Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
if (MessageBox(nullptr,TEXT("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?"),TEXT("NeHe GL"),MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen = FALSE; // Select Windowed Mode (Fullscreen = FALSE)
}
else
{
//Popup Messagebox: Closing
MessageBox(nullptr, TEXT("Program will close now."), TEXT("ERROR"), MB_OK|MB_ICONSTOP);
return FALSE; //exit, return false
}
}
}
if (fullscreen) // when mode really succeeded
{
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP;
ShowCursor(FALSE);
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window extended style
dwStyle=WS_OVERLAPPEDWINDOW; // Windows style
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
if (nullptr == (g_hWnd=CreateWindowEx(dwExStyle, // Extended Style For The Window
TEXT("OpenGL"), // Class Name
UTFConverter(title).c_wstr(), // Window Title
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN | // Required Window Style
dwStyle, // Selected WIndow Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calc adjusted Window Width
WindowRect.bottom-WindowRect.top, // Calc adjustes Window Height
nullptr, // No Parent Window
nullptr, // No Menu
g_hInstance, // Instance
nullptr ))) // Don't pass anything To WM_CREATE
{
abortGLInit("Window Creation Error.");
return FALSE;
}
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
BYTE(bits), // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (nullptr == (hDC=GetDC(g_hWnd))) // Did we get the Device Context?
{
abortGLInit("Can't Create A GL Device Context.");
return FALSE;
}
if (0 == (PixelFormat=ChoosePixelFormat(hDC, &pfd))) // Did We Find a matching pixel Format?
{
abortGLInit("Can't Find Suitable PixelFormat");
return FALSE;
}
if (!SetPixelFormat(hDC, PixelFormat, &pfd))
{
abortGLInit("Can't Set The PixelFormat");
return FALSE;
}
if (nullptr == (hRC=wglCreateContext(hDC)))
{
abortGLInit("Can't Create A GL Rendering Context.");
return FALSE;
}
if (!(wglMakeCurrent(hDC,hRC))) // Try to activate the rendering context
{
abortGLInit("Can't Activate The Rendering Context");
return FALSE;
}
//// *** everything okay ***
ShowWindow(g_hWnd, SW_SHOW); // Show The Window
SetForegroundWindow(g_hWnd); // Slightly Higher Prio
SetFocus(g_hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL())
{
abortGLInit("Initialization failed");
return FALSE;
}
return TRUE;
}
void cleanup()
{
freeTextureIds();
destroyAILogger();
if (g_hWnd)
KillGLWindow();
}
LRESULT CALLBACK WndProc(HWND hWnd, // Handles for this Window
UINT uMsg, // Message for this Window
WPARAM wParam, // additional message Info
LPARAM lParam) // additional message Info
{
switch (uMsg) // check for Window Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
if (!HIWORD(wParam)) // Check Minimization State
{
active=TRUE;
}
else
{
active=FALSE;
}
return 0; // return To The Message Loop
}
case WM_SYSCOMMAND: // Interrupt System Commands
{
switch (wParam)
{
case SC_SCREENSAVE: // Screen-saver trying to start
case SC_MONITORPOWER: // Monitor trying to enter power-safe
return 0;
}
break;
}
case WM_CLOSE: // close message received?
{
PostQuitMessage(0); // Send WM_QUIT quit message
return 0; // Jump Back
}
case WM_KEYDOWN: // Is a key pressed?
{
keys[wParam] = TRUE; // If so, Mark it as true
return 0;
}
case WM_KEYUP: // Has Key Been released?
{
keys[wParam] = FALSE; // If so, Mark It As FALSE
return 0;
}
case WM_SIZE: // Resize The OpenGL Window
{
ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord-Width, HiWord-Height
return 0;
}
}
// Pass All unhandled Messaged To DefWindowProc
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain( HINSTANCE /*hInstance*/, // The instance
HINSTANCE /*hPrevInstance*/, // Previous instance
LPSTR /*lpCmdLine*/, // Command Line Parameters
int /*nShowCmd*/ ) // Window Show State
{
MSG msg = {};
BOOL done=FALSE;
createAILogger();
logInfo("App fired!");
// Check the command line for an override file path.
int argc;
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if (argv != nullptr && argc > 1)
{
std::wstring modelpathW(argv[1]);
modelpath = UTFConverter(modelpathW).str();
}
if (!Import3DFromFile(modelpath))
{
cleanup();
return 0;
}
logInfo("=============== Post Import ====================");
if (MessageBox(nullptr, TEXT("Would You Like To Run In Fullscreen Mode?"), TEXT("Start Fullscreen?"), MB_YESNO|MB_ICONEXCLAMATION)==IDNO)
{
fullscreen=FALSE;
}
if (!CreateGLWindow(windowTitle, 640, 480, 16, fullscreen))
{
cleanup();
return 0;
}
while(!done) // Game Loop
{
if (PeekMessage(&msg, nullptr, 0,0, PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
done=TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
// Draw The Scene. Watch For ESC Key And Quit Messaged From DrawGLScene()
if (active)
{
if (keys[VK_ESCAPE])
{
done=TRUE;
}
else
{
DrawGLScene();
SwapBuffers(hDC);
}
}
if (keys[VK_F1])
{
keys[VK_F1]=FALSE;
KillGLWindow();
fullscreen=!fullscreen;
if (!CreateGLWindow(windowTitle, 640, 480, 16, fullscreen))
{
cleanup();
return 0;
}
}
}
}
// *** cleanup ***
cleanup();
return static_cast<int>(msg.wParam);
}