- clean working copy for leaving SVN

This commit is contained in:
2022-06-28 19:04:46 +02:00
parent 62a2d47cb3
commit 762b8f0e7d
1966 changed files with 699872 additions and 126 deletions
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist>
<dict>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.OpenGLAppExample</string>
<key>CFBundleName</key>
<string>OpenGLAppExample</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{3AF5984B-1995-D9AA-6A48-A11A7E29B8ED}") = "OpenGLAppExample", "OpenGLAppExample.vcxproj", "{7C7408CA-ACB1-2C65-426D-235C519770A9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7C7408CA-ACB1-2C65-426D-235C519770A9}.Debug|Win32.ActiveCfg = Debug|Win32
{7C7408CA-ACB1-2C65-426D-235C519770A9}.Debug|Win32.Build.0 = Debug|Win32
{7C7408CA-ACB1-2C65-426D-235C519770A9}.Release|Win32.ActiveCfg = Release|Win32
{7C7408CA-ACB1-2C65-426D-235C519770A9}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,29 @@
#ifdef JUCE_USER_DEFINED_RC_FILE
#include JUCE_USER_DEFINED_RC_FILE
#else
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "FileDescription", "OpenGLAppExample\0"
VALUE "FileVersion", "1.0.0\0"
VALUE "ProductName", "OpenGLAppExample\0"
VALUE "ProductVersion", "1.0.0\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 65001
END
END
#endif
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist>
<dict>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.OpenGLAppExample</string>
<key>CFBundleName</key>
<string>OpenGLAppExample</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,58 @@
{
"images": [
{
"idiom": "iphone",
"size": "29x29",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "40x40",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "60x60",
"scale": "2x"
},
{
"idiom": "iphone",
"size": "60x60",
"scale": "3x"
},
{
"idiom": "ipad",
"size": "29x29",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "29x29",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "40x40",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "40x40",
"scale": "2x"
},
{
"idiom": "ipad",
"size": "76x76",
"scale": "1x"
},
{
"idiom": "ipad",
"size": "76x76",
"scale": "2x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
@@ -0,0 +1,50 @@
{
"images": [
{
"orientation": "portrait",
"idiom": "iphone",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "2x"
},
{
"orientation": "portrait",
"idiom": "iphone",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "2x"
},
{
"orientation": "portrait",
"idiom": "ipad",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "1x"
},
{
"orientation": "landscape",
"idiom": "ipad",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "1x"
},
{
"orientation": "portrait",
"idiom": "ipad",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "2x"
},
{
"orientation": "landscape",
"idiom": "ipad",
"extent": "full-screen",
"minimum-system-version": "7.0",
"scale": "2x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
@@ -0,0 +1,196 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
There's a section below where you can add your own custom code safely, and the
Introjucer will preserve the contents of that block, but the best way to change
any of these definitions is by using the Introjucer's project settings.
Any commented-out settings will assume their default values.
*/
#ifndef __JUCE_APPCONFIG_C3KRLE__
#define __JUCE_APPCONFIG_C3KRLE__
//==============================================================================
// [BEGIN_USER_CODE_SECTION]
// (You can add your own code in this section, and the Introjucer will not overwrite it)
// [END_USER_CODE_SECTION]
//==============================================================================
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1
#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1
#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1
#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1
#define JUCE_MODULE_AVAILABLE_juce_core 1
#define JUCE_MODULE_AVAILABLE_juce_cryptography 1
#define JUCE_MODULE_AVAILABLE_juce_data_structures 1
#define JUCE_MODULE_AVAILABLE_juce_events 1
#define JUCE_MODULE_AVAILABLE_juce_graphics 1
#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1
#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1
#define JUCE_MODULE_AVAILABLE_juce_opengl 1
#define JUCE_MODULE_AVAILABLE_juce_video 1
//==============================================================================
// juce_audio_devices flags:
#ifndef JUCE_ASIO
//#define JUCE_ASIO
#endif
#ifndef JUCE_WASAPI
//#define JUCE_WASAPI
#endif
#ifndef JUCE_DIRECTSOUND
//#define JUCE_DIRECTSOUND
#endif
#ifndef JUCE_ALSA
//#define JUCE_ALSA
#endif
#ifndef JUCE_JACK
//#define JUCE_JACK
#endif
#ifndef JUCE_USE_ANDROID_OPENSLES
//#define JUCE_USE_ANDROID_OPENSLES
#endif
#ifndef JUCE_USE_CDREADER
//#define JUCE_USE_CDREADER
#endif
#ifndef JUCE_USE_CDBURNER
//#define JUCE_USE_CDBURNER
#endif
//==============================================================================
// juce_audio_formats flags:
#ifndef JUCE_USE_FLAC
//#define JUCE_USE_FLAC
#endif
#ifndef JUCE_USE_OGGVORBIS
//#define JUCE_USE_OGGVORBIS
#endif
#ifndef JUCE_USE_MP3AUDIOFORMAT
//#define JUCE_USE_MP3AUDIOFORMAT
#endif
#ifndef JUCE_USE_LAME_AUDIO_FORMAT
//#define JUCE_USE_LAME_AUDIO_FORMAT
#endif
#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT
//#define JUCE_USE_WINDOWS_MEDIA_FORMAT
#endif
//==============================================================================
// juce_audio_processors flags:
#ifndef JUCE_PLUGINHOST_VST
//#define JUCE_PLUGINHOST_VST
#endif
#ifndef JUCE_PLUGINHOST_VST3
//#define JUCE_PLUGINHOST_VST3
#endif
#ifndef JUCE_PLUGINHOST_AU
//#define JUCE_PLUGINHOST_AU
#endif
//==============================================================================
// juce_core flags:
#ifndef JUCE_FORCE_DEBUG
//#define JUCE_FORCE_DEBUG
#endif
#ifndef JUCE_LOG_ASSERTIONS
//#define JUCE_LOG_ASSERTIONS
#endif
#ifndef JUCE_CHECK_MEMORY_LEAKS
//#define JUCE_CHECK_MEMORY_LEAKS
#endif
#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
//#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
#endif
#ifndef JUCE_INCLUDE_ZLIB_CODE
//#define JUCE_INCLUDE_ZLIB_CODE
#endif
//==============================================================================
// juce_graphics flags:
#ifndef JUCE_USE_COREIMAGE_LOADER
//#define JUCE_USE_COREIMAGE_LOADER
#endif
#ifndef JUCE_USE_DIRECTWRITE
//#define JUCE_USE_DIRECTWRITE
#endif
//==============================================================================
// juce_gui_basics flags:
#ifndef JUCE_ENABLE_REPAINT_DEBUGGING
//#define JUCE_ENABLE_REPAINT_DEBUGGING
#endif
#ifndef JUCE_USE_XSHM
//#define JUCE_USE_XSHM
#endif
#ifndef JUCE_USE_XRENDER
//#define JUCE_USE_XRENDER
#endif
#ifndef JUCE_USE_XCURSOR
//#define JUCE_USE_XCURSOR
#endif
//==============================================================================
// juce_gui_extra flags:
#ifndef JUCE_WEB_BROWSER
//#define JUCE_WEB_BROWSER
#endif
#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
//#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR
#endif
//==============================================================================
// juce_video flags:
#ifndef JUCE_DIRECTSHOW
//#define JUCE_DIRECTSHOW
#endif
#ifndef JUCE_MEDIAFOUNDATION
//#define JUCE_MEDIAFOUNDATION
#endif
#ifndef JUCE_QUICKTIME
//#define JUCE_QUICKTIME
#endif
#ifndef JUCE_USE_CAMERA
//#define JUCE_USE_CAMERA
#endif
#endif // __JUCE_APPCONFIG_C3KRLE__
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
/* =========================================================================================
This is an auto-generated file: Any edits you make may be overwritten!
*/
#ifndef BINARYDATA_H_65160528_INCLUDED
#define BINARYDATA_H_65160528_INCLUDED
namespace BinaryData
{
extern const char* teapot_obj;
const int teapot_objSize = 95000;
// Points to the start of a list of resource names.
extern const char* namedResourceList[];
// Number of elements in the namedResourceList array.
const int namedResourceListSize = 1;
// If you provide the name of one of the binary resource variables above, this function will
// return the corresponding data and its size (or a null pointer if the name isn't found).
const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) throw();
}
#endif
@@ -0,0 +1,47 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
This is the header file that your files should include in order to get all the
JUCE library headers. You should avoid including the JUCE headers directly in
your own source files, because that wouldn't pick up the correct configuration
options for your app.
*/
#ifndef __APPHEADERFILE_C3KRLE__
#define __APPHEADERFILE_C3KRLE__
#include "AppConfig.h"
#include "modules/juce_audio_basics/juce_audio_basics.h"
#include "modules/juce_audio_devices/juce_audio_devices.h"
#include "modules/juce_audio_formats/juce_audio_formats.h"
#include "modules/juce_audio_processors/juce_audio_processors.h"
#include "modules/juce_core/juce_core.h"
#include "modules/juce_cryptography/juce_cryptography.h"
#include "modules/juce_data_structures/juce_data_structures.h"
#include "modules/juce_events/juce_events.h"
#include "modules/juce_graphics/juce_graphics.h"
#include "modules/juce_gui_basics/juce_gui_basics.h"
#include "modules/juce_gui_extra/juce_gui_extra.h"
#include "modules/juce_opengl/juce_opengl.h"
#include "modules/juce_video/juce_video.h"
#include "BinaryData.h"
#if ! DONT_SET_USING_JUCE_NAMESPACE
// If your code uses a lot of JUCE classes, then this will obviously save you
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.
using namespace juce;
#endif
#if ! JUCE_DONT_DECLARE_PROJECTINFO
namespace ProjectInfo
{
const char* const projectName = "OpenGLAppExample";
const char* const versionString = "1.0.0";
const int versionNumber = 0x10000;
}
#endif
#endif // __APPHEADERFILE_C3KRLE__
@@ -0,0 +1,12 @@
Important Note!!
================
The purpose of this folder is to contain files that are auto-generated by the Introjucer,
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
the Introjucer saves your project.
Therefore, it's a bad idea to make any manual changes to the files in here, or to
put any of your own files in here if you don't want to lose them. (Of course you may choose
to add the folder's contents to your version-control system so that you can re-merge your own
modifications after the Introjucer has saved its changes).
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_audio_basics/juce_audio_basics.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_audio_devices/juce_audio_devices.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_audio_formats/juce_audio_formats.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_audio_processors/juce_audio_processors.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_core/juce_core.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_cryptography/juce_cryptography.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_data_structures/juce_data_structures.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_events/juce_events.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_graphics/juce_graphics.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_gui_basics/juce_gui_basics.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_gui_extra/juce_gui_extra.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_opengl/juce_opengl.h"
@@ -0,0 +1,5 @@
// This is an auto-generated file to redirect any included
// module headers to the correct external folder.
#include "../../../../../modules/juce_video/juce_video.h"
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<JUCERPROJECT id="c3KrlE" name="OpenGLAppExample" projectType="guiapp" version="1.0.0"
bundleIdentifier="com.yourcompany.OpenGLAppExample" includeBinaryInAppConfig="1"
jucerVersion="3.1.0">
<MAINGROUP id="amjEXL" name="OpenGLAppExample">
<GROUP id="{F5EA45A1-E25D-1821-14F8-EBCFBA9B2B81}" name="Shaders">
<FILE id="D3dDWc" name="FragmentShader.glsl" compile="1" resource="0"
file="Source/FragmentShader.glsl"/>
<FILE id="l2YQJq" name="VertexShader.glsl" compile="1" resource="0"
file="Source/VertexShader.glsl"/>
</GROUP>
<GROUP id="{28FE2D12-A88D-07E2-72CF-CD04014CF225}" name="Source">
<GROUP id="{666960E2-D311-806A-1FE7-A27057939840}" name="Resources">
<FILE id="TK8Cyp" name="teapot.obj" compile="0" resource="1" file="Source/Resources/teapot.obj"/>
</GROUP>
<FILE id="uJnfj6" name="MainComponent.cpp" compile="1" resource="0"
file="Source/MainComponent.cpp"/>
<FILE id="vbnESJ" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/>
<FILE id="g9rTnA" name="WavefrontObjParser.h" compile="0" resource="0"
file="Source/Resources/WavefrontObjParser.h"/>
</GROUP>
</MAINGROUP>
<EXPORTFORMATS>
<XCODE_MAC targetFolder="Builds/MacOSX">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" osxSDK="default" osxCompatibility="default" osxArchitecture="default"
isDebug="1" optimisation="1" targetName="OpenGLAppExample"/>
<CONFIGURATION name="Release" osxSDK="default" osxCompatibility="default" osxArchitecture="default"
isDebug="0" optimisation="2" targetName="OpenGLAppExample"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_core" path="../../modules"/>
<MODULEPATH id="juce_events" path="../../modules"/>
<MODULEPATH id="juce_graphics" path="../../modules"/>
<MODULEPATH id="juce_data_structures" path="../../modules"/>
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
<MODULEPATH id="juce_gui_extra" path="../../modules"/>
<MODULEPATH id="juce_cryptography" path="../../modules"/>
<MODULEPATH id="juce_video" path="../../modules"/>
<MODULEPATH id="juce_opengl" path="../../modules"/>
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
<MODULEPATH id="juce_audio_processors" path="../../modules"/>
</MODULEPATHS>
</XCODE_MAC>
<XCODE_IPHONE targetFolder="Builds/iOS">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" iosCompatibility="default" isDebug="1" optimisation="1"
targetName="OpenGLAppExample"/>
<CONFIGURATION name="Release" iosCompatibility="default" isDebug="0" optimisation="2"
targetName="OpenGLAppExample"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_core" path="../../modules"/>
<MODULEPATH id="juce_events" path="../../modules"/>
<MODULEPATH id="juce_graphics" path="../../modules"/>
<MODULEPATH id="juce_data_structures" path="../../modules"/>
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
<MODULEPATH id="juce_gui_extra" path="../../modules"/>
<MODULEPATH id="juce_cryptography" path="../../modules"/>
<MODULEPATH id="juce_video" path="../../modules"/>
<MODULEPATH id="juce_opengl" path="../../modules"/>
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
<MODULEPATH id="juce_audio_processors" path="../../modules"/>
</MODULEPATHS>
</XCODE_IPHONE>
<VS2010 targetFolder="Builds/VisualStudio2010">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
isDebug="1" optimisation="1" targetName="OpenGLAppExample"/>
<CONFIGURATION name="Release" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit"
isDebug="0" optimisation="2" targetName="OpenGLAppExample"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_core" path="../../modules"/>
<MODULEPATH id="juce_events" path="../../modules"/>
<MODULEPATH id="juce_graphics" path="../../modules"/>
<MODULEPATH id="juce_data_structures" path="../../modules"/>
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
<MODULEPATH id="juce_gui_extra" path="../../modules"/>
<MODULEPATH id="juce_cryptography" path="../../modules"/>
<MODULEPATH id="juce_video" path="../../modules"/>
<MODULEPATH id="juce_opengl" path="../../modules"/>
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
<MODULEPATH id="juce_audio_processors" path="../../modules"/>
</MODULEPATHS>
</VS2010>
</EXPORTFORMATS>
<MODULES>
<MODULES id="juce_audio_basics" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_audio_devices" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_audio_formats" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_audio_processors" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_core" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_cryptography" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_data_structures" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_events" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_graphics" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_gui_basics" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_gui_extra" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_opengl" showAllCode="1" useLocalCopy="0"/>
<MODULES id="juce_video" showAllCode="1" useLocalCopy="0"/>
</MODULES>
<JUCEOPTIONS/>
</JUCERPROJECT>
@@ -0,0 +1,10 @@
/*
==============================================================================
FragmentShader.cpp
Created: 11 Nov 2014 12:17:53pm
Author: Felix Faire
==============================================================================
*/
@@ -0,0 +1,102 @@
/*
==============================================================================
This file was auto-generated by the Introjucer!
It contains the basic startup code for a Juce application.
==============================================================================
*/
#include "../JuceLibraryCode/JuceHeader.h"
Component* createMainContentComponent();
//==============================================================================
class OpenGLAppExampleApplication : public JUCEApplication
{
public:
//==============================================================================
OpenGLAppExampleApplication() {}
const String getApplicationName() override { return ProjectInfo::projectName; }
const String getApplicationVersion() override { return ProjectInfo::versionString; }
bool moreThanOneInstanceAllowed() override { return true; }
//==============================================================================
void initialise (const String& commandLine) override
{
// This method is where you should put your application's initialisation code..
mainWindow = new MainWindow (getApplicationName());
}
void shutdown() override
{
// Add your application's shutdown code here..
mainWindow = nullptr; // (deletes our window)
}
//==============================================================================
void systemRequestedQuit() override
{
// This is called when the app is being asked to quit: you can ignore this
// request and let the app carry on running, or call quit() to allow the app to close.
quit();
}
void anotherInstanceStarted (const String& commandLine) override
{
// When another instance of the app is launched while this one is running,
// this method is invoked, and the commandLine parameter tells you what
// the other instance's command-line arguments were.
}
//==============================================================================
/*
This class implements the desktop window that contains an instance of
our MainContentComponent class.
*/
class MainWindow : public DocumentWindow
{
public:
MainWindow (String name) : DocumentWindow (name,
Colours::lightgrey,
DocumentWindow::allButtons)
{
setUsingNativeTitleBar (true);
setContentOwned (createMainContentComponent(), true);
setResizable (true, true);
centreWithSize (getWidth(), getHeight());
setVisible (true);
}
void closeButtonPressed() override
{
// This is called when the user tries to close this window. Here, we'll just
// ask the app to quit when this happens, but you can change this to do
// whatever you need.
JUCEApplication::getInstance()->systemRequestedQuit();
}
/* Note: Be careful if you override any DocumentWindow methods - the base
class uses a lot of them, so by overriding you might break its functionality.
It's best to do all your work in your content component instead, but if
you really have to override any DocumentWindow methods, make sure your
subclass also calls the superclass's method.
*/
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
};
private:
ScopedPointer<MainWindow> mainWindow;
};
//==============================================================================
// This macro generates the main() routine that launches the app.
START_JUCE_APPLICATION (OpenGLAppExampleApplication)
@@ -0,0 +1,389 @@
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#ifndef MAINCOMPONENT_H_INCLUDED
#define MAINCOMPONENT_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
#include "Resources/WavefrontObjParser.h"
//==============================================================================
/*
This component lives inside our window, and this is where you should put all
your controls and content.
*/
class MainContentComponent : public OpenGLAppComponent
{
public:
//==============================================================================
MainContentComponent()
{
setSize (800, 600);
}
~MainContentComponent()
{
shutdownOpenGL();
}
void initialise() override
{
createShaders();
}
void shutdown() override
{
shader = nullptr;
shape = nullptr;
attributes = nullptr;
uniforms = nullptr;
}
Matrix3D<float> getProjectionMatrix() const
{
float w = 1.0f / (0.5f + 0.1f);
float h = w * getLocalBounds().toFloat().getAspectRatio (false);
return Matrix3D<float>::fromFrustum (-w, w, -h, h, 4.0f, 30.0f);
}
Matrix3D<float> getViewMatrix() const
{
Matrix3D<float> viewMatrix (Vector3D<float> (0.0f, 0.0f, -10.0f));
Matrix3D<float> rotationMatrix
= viewMatrix.rotated (Vector3D<float> (-0.3f, 5.0f * std::sin (getFrameCounter() * 0.01f), 0.0f));
return viewMatrix * rotationMatrix;
}
void render() override
{
jassert (OpenGLHelpers::isContextActive());
const float desktopScale = (float) openGLContext.getRenderingScale();
OpenGLHelpers::clear (Colour::greyLevel (0.1f));
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glViewport (0, 0, roundToInt (desktopScale * getWidth()), roundToInt (desktopScale * getHeight()));
shader->use();
if (uniforms->projectionMatrix != nullptr)
uniforms->projectionMatrix->setMatrix4 (getProjectionMatrix().mat, 1, false);
if (uniforms->viewMatrix != nullptr)
uniforms->viewMatrix->setMatrix4 (getViewMatrix().mat, 1, false);
shape->draw (openGLContext, *attributes);
// Reset the element buffers so child Components draw correctly
openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, 0);
openGLContext.extensions.glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
}
void paint (Graphics& g) override
{
// You can add your component specific drawing code here!
// This will draw over the top of the openGL background.
g.setColour(Colours::white);
g.setFont (20);
g.drawText ("OpenGL Example", 25, 20, 300, 30, Justification::left);
g.drawLine (20, 20, 170, 20);
g.drawLine (20, 50, 170, 50);
}
void resized() override
{
// This is called when the MainContentComponent is resized.
// If you add any child components, this is where you should
// update their positions.
}
void createShaders()
{
vertexShader =
"attribute vec4 position;\n"
"attribute vec4 sourceColour;\n"
"attribute vec2 texureCoordIn;\n"
"\n"
"uniform mat4 projectionMatrix;\n"
"uniform mat4 viewMatrix;\n"
"\n"
"varying vec4 destinationColour;\n"
"varying vec2 textureCoordOut;\n"
"\n"
"void main()\n"
"{\n"
" destinationColour = sourceColour;\n"
" textureCoordOut = texureCoordIn;\n"
" gl_Position = projectionMatrix * viewMatrix * position;\n"
"}\n";
fragmentShader =
#if JUCE_OPENGL_ES
"varying lowp vec4 destinationColour;\n"
"varying lowp vec2 textureCoordOut;\n"
#else
"varying vec4 destinationColour;\n"
"varying vec2 textureCoordOut;\n"
#endif
"\n"
"void main()\n"
"{\n"
" vec4 colour = vec4(0.95, 0.57, 0.03, 0.7);\n"
" gl_FragColor = colour;\n"
"}\n";
ScopedPointer<OpenGLShaderProgram> newShader (new OpenGLShaderProgram (openGLContext));
String statusText;
if (newShader->addVertexShader (OpenGLHelpers::translateVertexShaderToV3 (vertexShader))
&& newShader->addFragmentShader (OpenGLHelpers::translateFragmentShaderToV3 (fragmentShader))
&& newShader->link())
{
shape = nullptr;
attributes = nullptr;
uniforms = nullptr;
shader = newShader;
shader->use();
shape = new Shape (openGLContext);
attributes = new Attributes (openGLContext, *shader);
uniforms = new Uniforms (openGLContext, *shader);
statusText = "GLSL: v" + String (OpenGLShaderProgram::getLanguageVersion(), 2);
}
else
{
statusText = newShader->getLastError();
}
}
private:
//==============================================================================
struct Vertex
{
float position[3];
float normal[3];
float colour[4];
float texCoord[2];
};
//==============================================================================
// This class just manages the attributes that the shaders use.
struct Attributes
{
Attributes (OpenGLContext& openGLContext, OpenGLShaderProgram& shader)
{
position = createAttribute (openGLContext, shader, "position");
normal = createAttribute (openGLContext, shader, "normal");
sourceColour = createAttribute (openGLContext, shader, "sourceColour");
texureCoordIn = createAttribute (openGLContext, shader, "texureCoordIn");
}
void enable (OpenGLContext& openGLContext)
{
if (position != nullptr)
{
openGLContext.extensions.glVertexAttribPointer (position->attributeID, 3, GL_FLOAT, GL_FALSE, sizeof (Vertex), 0);
openGLContext.extensions.glEnableVertexAttribArray (position->attributeID);
}
if (normal != nullptr)
{
openGLContext.extensions.glVertexAttribPointer (normal->attributeID, 3, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid*) (sizeof (float) * 3));
openGLContext.extensions.glEnableVertexAttribArray (normal->attributeID);
}
if (sourceColour != nullptr)
{
openGLContext.extensions.glVertexAttribPointer (sourceColour->attributeID, 4, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid*) (sizeof (float) * 6));
openGLContext.extensions.glEnableVertexAttribArray (sourceColour->attributeID);
}
if (texureCoordIn != nullptr)
{
openGLContext.extensions.glVertexAttribPointer (texureCoordIn->attributeID, 2, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid*) (sizeof (float) * 10));
openGLContext.extensions.glEnableVertexAttribArray (texureCoordIn->attributeID);
}
}
void disable (OpenGLContext& openGLContext)
{
if (position != nullptr) openGLContext.extensions.glDisableVertexAttribArray (position->attributeID);
if (normal != nullptr) openGLContext.extensions.glDisableVertexAttribArray (normal->attributeID);
if (sourceColour != nullptr) openGLContext.extensions.glDisableVertexAttribArray (sourceColour->attributeID);
if (texureCoordIn != nullptr) openGLContext.extensions.glDisableVertexAttribArray (texureCoordIn->attributeID);
}
ScopedPointer<OpenGLShaderProgram::Attribute> position, normal, sourceColour, texureCoordIn;
private:
static OpenGLShaderProgram::Attribute* createAttribute (OpenGLContext& openGLContext,
OpenGLShaderProgram& shader,
const char* attributeName)
{
if (openGLContext.extensions.glGetAttribLocation (shader.getProgramID(), attributeName) < 0)
return nullptr;
return new OpenGLShaderProgram::Attribute (shader, attributeName);
}
};
//==============================================================================
// This class just manages the uniform values that the demo shaders use.
struct Uniforms
{
Uniforms (OpenGLContext& openGLContext, OpenGLShaderProgram& shader)
{
projectionMatrix = createUniform (openGLContext, shader, "projectionMatrix");
viewMatrix = createUniform (openGLContext, shader, "viewMatrix");
}
ScopedPointer<OpenGLShaderProgram::Uniform> projectionMatrix, viewMatrix;
private:
static OpenGLShaderProgram::Uniform* createUniform (OpenGLContext& openGLContext,
OpenGLShaderProgram& shader,
const char* uniformName)
{
if (openGLContext.extensions.glGetUniformLocation (shader.getProgramID(), uniformName) < 0)
return nullptr;
return new OpenGLShaderProgram::Uniform (shader, uniformName);
}
};
//==============================================================================
/** This loads a 3D model from an OBJ file and converts it into some vertex buffers
that we can draw.
*/
struct Shape
{
Shape (OpenGLContext& openGLContext)
{
if (shapeFile.load (BinaryData::teapot_obj).wasOk())
for (int i = 0; i < shapeFile.shapes.size(); ++i)
vertexBuffers.add (new VertexBuffer (openGLContext, *shapeFile.shapes.getUnchecked(i)));
}
void draw (OpenGLContext& openGLContext, Attributes& attributes)
{
for (int i = 0; i < vertexBuffers.size(); ++i)
{
VertexBuffer& vertexBuffer = *vertexBuffers.getUnchecked (i);
vertexBuffer.bind();
attributes.enable (openGLContext);
glDrawElements (GL_TRIANGLES, vertexBuffer.numIndices, GL_UNSIGNED_INT, 0);
attributes.disable (openGLContext);
}
}
private:
struct VertexBuffer
{
VertexBuffer (OpenGLContext& context, WavefrontObjFile::Shape& shape) : openGLContext (context)
{
numIndices = shape.mesh.indices.size();
openGLContext.extensions.glGenBuffers (1, &vertexBuffer);
openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, vertexBuffer);
Array<Vertex> vertices;
createVertexListFromMesh (shape.mesh, vertices, Colours::green);
openGLContext.extensions.glBufferData (GL_ARRAY_BUFFER, vertices.size() * sizeof (Vertex),
vertices.getRawDataPointer(), GL_STATIC_DRAW);
openGLContext.extensions.glGenBuffers (1, &indexBuffer);
openGLContext.extensions.glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
openGLContext.extensions.glBufferData (GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof (juce::uint32),
shape.mesh.indices.getRawDataPointer(), GL_STATIC_DRAW);
}
~VertexBuffer()
{
openGLContext.extensions.glDeleteBuffers (1, &vertexBuffer);
openGLContext.extensions.glDeleteBuffers (1, &indexBuffer);
}
void bind()
{
openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, vertexBuffer);
openGLContext.extensions.glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
}
GLuint vertexBuffer, indexBuffer;
int numIndices;
OpenGLContext& openGLContext;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VertexBuffer)
};
WavefrontObjFile shapeFile;
OwnedArray<VertexBuffer> vertexBuffers;
static void createVertexListFromMesh (const WavefrontObjFile::Mesh& mesh, Array<Vertex>& list, Colour colour)
{
const float scale = 0.2f;
WavefrontObjFile::TextureCoord defaultTexCoord = { 0.5f, 0.5f };
WavefrontObjFile::Vertex defaultNormal = { 0.5f, 0.5f, 0.5f };
for (int i = 0; i < mesh.vertices.size(); ++i)
{
const WavefrontObjFile::Vertex& v = mesh.vertices.getReference (i);
const WavefrontObjFile::Vertex& n
= i < mesh.normals.size() ? mesh.normals.getReference (i) : defaultNormal;
const WavefrontObjFile::TextureCoord& tc
= i < mesh.textureCoords.size() ? mesh.textureCoords.getReference (i) : defaultTexCoord;
Vertex vert =
{
{ scale * v.x, scale * v.y, scale * v.z, },
{ scale * n.x, scale * n.y, scale * n.z, },
{ colour.getFloatRed(), colour.getFloatGreen(), colour.getFloatBlue(), colour.getFloatAlpha() },
{ tc.x, tc.y }
};
list.add (vert);
}
}
};
const char* vertexShader;
const char* fragmentShader;
ScopedPointer<OpenGLShaderProgram> shader;
ScopedPointer<Shape> shape;
ScopedPointer<Attributes> attributes;
ScopedPointer<Uniforms> uniforms;
String newVertexShader, newFragmentShader;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
// (This function is called by the app startup code to create our main component)
Component* createMainContentComponent() { return new MainContentComponent(); }
#endif // MAINCOMPONENT_H_INCLUDED
@@ -0,0 +1,359 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-12 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include <map>
//==============================================================================
/**
This is a quick-and-dirty parser for the 3D OBJ file format.
Just call load() and if there aren't any errors, the 'shapes' array should
be filled with all the shape objects that were loaded from the file.
*/
class WavefrontObjFile
{
public:
WavefrontObjFile() {}
Result load (const String& objFileContent)
{
shapes.clear();
return parseObjFile (StringArray::fromLines (objFileContent));
}
Result load (const File& file)
{
sourceFile = file;
return load (file.loadFileAsString());
}
//==============================================================================
typedef juce::uint32 Index;
struct Vertex { float x, y, z; };
struct TextureCoord { float x, y; };
struct Mesh
{
Array<Vertex> vertices, normals;
Array<TextureCoord> textureCoords;
Array<Index> indices;
};
struct Material
{
Material() noexcept : shininess (1.0f), refractiveIndex (0.0f)
{
zerostruct (ambient);
zerostruct (diffuse);
zerostruct (specular);
zerostruct (transmittance);
zerostruct (emission);
}
String name;
Vertex ambient, diffuse, specular, transmittance, emission;
float shininess, refractiveIndex;
String ambientTextureName, diffuseTextureName,
specularTextureName, normalTextureName;
StringPairArray parameters;
};
struct Shape
{
String name;
Mesh mesh;
Material material;
};
OwnedArray<Shape> shapes;
private:
//==============================================================================
File sourceFile;
struct TripleIndex
{
TripleIndex() noexcept : vertexIndex (-1), textureIndex (-1), normalIndex (-1) {}
bool operator< (const TripleIndex& other) const noexcept { return vertexIndex < other.vertexIndex; }
int vertexIndex, textureIndex, normalIndex;
};
struct IndexMap
{
std::map<TripleIndex, Index> map;
Index getIndexFor (TripleIndex i, Mesh& newMesh, const Mesh& srcMesh)
{
const std::map<TripleIndex, Index>::iterator it (map.find (i));
if (it != map.end())
return it->second;
const Index index = (Index) newMesh.vertices.size();
if (isPositiveAndBelow (i.vertexIndex, srcMesh.vertices.size()))
newMesh.vertices.add (srcMesh.vertices.getReference (i.vertexIndex));
if (isPositiveAndBelow (i.normalIndex, srcMesh.normals.size()))
newMesh.normals.add (srcMesh.normals.getReference (i.normalIndex));
if (isPositiveAndBelow (i.textureIndex, srcMesh.textureCoords.size()))
newMesh.textureCoords.add (srcMesh.textureCoords.getReference (i.textureIndex));
map[i] = index;
return index;
}
};
static float parseFloat (String::CharPointerType& t)
{
t = t.findEndOfWhitespace();
return (float) CharacterFunctions::readDoubleValue (t);
}
static Vertex parseVertex (String::CharPointerType t)
{
Vertex v;
v.x = parseFloat (t);
v.y = parseFloat (t);
v.z = parseFloat (t);
return v;
}
static TextureCoord parseTextureCoord (String::CharPointerType t)
{
TextureCoord tc;
tc.x = parseFloat (t);
tc.y = parseFloat (t);
return tc;
}
static bool matchToken (String::CharPointerType& t, const char* token)
{
const int len = (int) strlen (token);
if (CharacterFunctions::compareUpTo (CharPointer_ASCII (token), t, len) == 0)
{
String::CharPointerType end = t + len;
if (end.isEmpty() || end.isWhitespace())
{
t = end.findEndOfWhitespace();
return true;
}
}
return false;
}
struct Face
{
Face (String::CharPointerType t)
{
while (! t.isEmpty())
triples.add (parseTriple (t));
}
Array<TripleIndex> triples;
void addIndices (Mesh& newMesh, const Mesh& srcMesh, IndexMap& indexMap)
{
TripleIndex i0 (triples[0]), i1, i2 (triples[1]);
for (int i = 2; i < triples.size(); ++i)
{
i1 = i2;
i2 = triples.getReference (i);
newMesh.indices.add (indexMap.getIndexFor (i0, newMesh, srcMesh));
newMesh.indices.add (indexMap.getIndexFor (i1, newMesh, srcMesh));
newMesh.indices.add (indexMap.getIndexFor (i2, newMesh, srcMesh));
}
}
static TripleIndex parseTriple (String::CharPointerType& t)
{
TripleIndex i;
t = t.findEndOfWhitespace();
i.vertexIndex = t.getIntValue32() - 1;
t = findEndOfFaceToken (t);
if (t.isEmpty() || t.getAndAdvance() != '/')
return i;
if (*t == '/')
{
++t;
}
else
{
i.textureIndex = t.getIntValue32() - 1;
t = findEndOfFaceToken (t);
if (t.isEmpty() || t.getAndAdvance() != '/')
return i;
}
i.normalIndex = t.getIntValue32() - 1;
t = findEndOfFaceToken (t);
return i;
}
static String::CharPointerType findEndOfFaceToken (String::CharPointerType t) noexcept
{
return CharacterFunctions::findEndOfToken (t, CharPointer_ASCII ("/ \t"), String::empty.getCharPointer());
}
};
static Shape* parseFaceGroup (const Mesh& srcMesh,
const Array<Face>& faceGroup,
const Material& material,
const String& name)
{
if (faceGroup.size() == 0)
return nullptr;
ScopedPointer<Shape> shape (new Shape());
shape->name = name;
shape->material = material;
IndexMap indexMap;
for (int i = 0; i < faceGroup.size(); ++i)
faceGroup.getReference(i).addIndices (shape->mesh, srcMesh, indexMap);
return shape.release();
}
Result parseObjFile (const StringArray& lines)
{
Mesh mesh;
Array<Face> faceGroup;
Array<Material> knownMaterials;
Material lastMaterial;
String lastName;
for (int lineNum = 0; lineNum < lines.size(); ++lineNum)
{
String::CharPointerType l = lines[lineNum].getCharPointer().findEndOfWhitespace();
if (matchToken (l, "v")) { mesh.vertices.add (parseVertex (l)); continue; }
if (matchToken (l, "vn")) { mesh.normals.add (parseVertex (l)); continue; }
if (matchToken (l, "vt")) { mesh.textureCoords.add (parseTextureCoord (l)); continue; }
if (matchToken (l, "f")) { faceGroup.add (Face (l)); continue; }
if (matchToken (l, "usemtl"))
{
const String name (String (l).trim());
for (int i = knownMaterials.size(); --i >= 0;)
{
if (knownMaterials.getReference(i).name == name)
{
lastMaterial = knownMaterials.getReference(i);
break;
}
}
continue;
}
if (matchToken (l, "mtllib"))
{
Result r = parseMaterial (knownMaterials, String (l).trim());
continue;
}
if (matchToken (l, "g") || matchToken (l, "o"))
{
if (Shape* shape = parseFaceGroup (mesh, faceGroup, lastMaterial, lastName))
shapes.add (shape);
faceGroup.clear();
lastName = StringArray::fromTokens (l, " \t", "")[0];
continue;
}
}
if (Shape* shape = parseFaceGroup (mesh, faceGroup, lastMaterial, lastName))
shapes.add (shape);
return Result::ok();
}
Result parseMaterial (Array<Material>& materials, const String& filename)
{
jassert (sourceFile.exists());
File f (sourceFile.getSiblingFile (filename));
if (! f.exists())
return Result::fail ("Cannot open file: " + filename);
StringArray lines;
lines.addLines (f.loadFileAsString());
materials.clear();
Material material;
for (int i = 0; i < lines.size(); ++i)
{
String::CharPointerType l (lines[i].getCharPointer().findEndOfWhitespace());
if (matchToken (l, "newmtl")) { materials.add (material); material.name = String (l).trim(); continue; }
if (matchToken (l, "Ka")) { material.ambient = parseVertex (l); continue; }
if (matchToken (l, "Kd")) { material.diffuse = parseVertex (l); continue; }
if (matchToken (l, "Ks")) { material.specular = parseVertex (l); continue; }
if (matchToken (l, "Kt")) { material.transmittance = parseVertex (l); continue; }
if (matchToken (l, "Ke")) { material.emission = parseVertex (l); continue; }
if (matchToken (l, "Ni")) { material.refractiveIndex = parseFloat (l); continue; }
if (matchToken (l, "Ns")) { material.shininess = parseFloat (l); continue; }
if (matchToken (l, "map_Ka")) { material.ambientTextureName = String (l).trim(); continue; }
if (matchToken (l, "map_Kd")) { material.diffuseTextureName = String (l).trim(); continue; }
if (matchToken (l, "map_Ks")) { material.specularTextureName = String (l).trim(); continue; }
if (matchToken (l, "map_Ns")) { material.normalTextureName = String (l).trim(); continue; }
StringArray tokens;
tokens.addTokens (l, " \t", "");
if (tokens.size() >= 2)
material.parameters.set (tokens[0].trim(), tokens[1].trim());
}
materials.add (material);
return Result::ok();
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavefrontObjFile)
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,9 @@
/*
==============================================================================
VertexShader.cpp
Created: 11 Nov 2014 12:17:40pm
Author: Felix Faire
==============================================================================
*/