Browse Source

OpenGL Example (unrefined)

tags/2021-05-28
Felix Faire 11 years ago
parent
commit
fb319467bd
47 changed files with 14498 additions and 2053 deletions
  1. BIN
      examples/AnimationAppExample/Builds/iOS/build/Debug/AnimationAppExample.app/AnimationAppExample
  2. BIN
      examples/AnimationAppExample/Builds/iOS/build/Debug/AnimationAppExample.app/LaunchImage-700-568h@2x.png
  3. +0
    -72
      examples/DemoChanges.txt
  4. +27
    -0
      examples/OpenGLAppExample/Builds/MacOSX/Info.plist
  5. +2134
    -0
      examples/OpenGLAppExample/Builds/MacOSX/OpenGLAppExample.xcodeproj/project.pbxproj
  6. BIN
      examples/OpenGLAppExample/Builds/MacOSX/RecentFilesMenuTemplate.nib
  7. +19
    -0
      examples/OpenGLAppExample/Builds/VisualStudio2010/OpenGLAppExample.sln
  8. +1703
    -0
      examples/OpenGLAppExample/Builds/VisualStudio2010/OpenGLAppExample.vcxproj
  9. +2918
    -0
      examples/OpenGLAppExample/Builds/VisualStudio2010/OpenGLAppExample.vcxproj.filters
  10. +29
    -0
      examples/OpenGLAppExample/Builds/VisualStudio2010/resources.rc
  11. +29
    -0
      examples/OpenGLAppExample/Builds/iOS/Info.plist
  12. +2124
    -0
      examples/OpenGLAppExample/Builds/iOS/OpenGLAppExample.xcodeproj/project.pbxproj
  13. +58
    -0
      examples/OpenGLAppExample/Builds/iOS/OpenGLAppExample/Images.xcassets/AppIcon.appiconset/Contents.json
  14. +50
    -0
      examples/OpenGLAppExample/Builds/iOS/OpenGLAppExample/Images.xcassets/LaunchImage.launchimage/Contents.json
  15. +196
    -0
      examples/OpenGLAppExample/JuceLibraryCode/AppConfig.h
  16. +1191
    -0
      examples/OpenGLAppExample/JuceLibraryCode/BinaryData.cpp
  17. +26
    -0
      examples/OpenGLAppExample/JuceLibraryCode/BinaryData.h
  18. +47
    -0
      examples/OpenGLAppExample/JuceLibraryCode/JuceHeader.h
  19. +12
    -0
      examples/OpenGLAppExample/JuceLibraryCode/ReadMe.txt
  20. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h
  21. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.h
  22. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h
  23. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h
  24. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_core/juce_core.h
  25. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.h
  26. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.h
  27. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_events/juce_events.h
  28. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.h
  29. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.h
  30. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.h
  31. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_opengl/juce_opengl.h
  32. +5
    -0
      examples/OpenGLAppExample/JuceLibraryCode/modules/juce_video/juce_video.h
  33. +111
    -0
      examples/OpenGLAppExample/OpenGLAppExample.jucer
  34. +10
    -0
      examples/OpenGLAppExample/Source/FragmentShader.glsl
  35. +102
    -0
      examples/OpenGLAppExample/Source/Main.cpp
  36. +403
    -0
      examples/OpenGLAppExample/Source/MainComponent.cpp
  37. +359
    -0
      examples/OpenGLAppExample/Source/Resources/WavefrontObjParser.h
  38. +2866
    -0
      examples/OpenGLAppExample/Source/Resources/teapot.obj
  39. +9
    -0
      examples/OpenGLAppExample/Source/VertexShader.glsl
  40. +2
    -2
      extras/Introjucer/JuceLibraryCode/BinaryData.cpp
  41. +2
    -2
      extras/Introjucer/Source/BinaryData/jucer_ContentCompTemplate.cpp
  42. +0
    -77
      extras/Introjucer/Source/BinaryData/jucer_OpenGLComponentTemplate.cpp
  43. +4
    -5
      extras/Introjucer/Source/BinaryData/jucer_OpenglComponentTemplate.cpp
  44. +0
    -698
      modules/juce_box2d/box2d/Collision/b2CollideEdge.cpp
  45. +0
    -249
      modules/juce_box2d/box2d/Collision/b2Collision.cpp
  46. +0
    -947
      modules/juce_browser_plugin_client/wrapper/juce_activex_gluecode.cpp
  47. +2
    -1
      modules/juce_opengl/utils/juce_OpenGLAppComponent.h

BIN
examples/AnimationAppExample/Builds/iOS/build/Debug/AnimationAppExample.app/AnimationAppExample View File


BIN
examples/AnimationAppExample/Builds/iOS/build/Debug/AnimationAppExample.app/LaunchImage-700-568h@2x.png View File

Before After
Width: 640  |  Height: 1136  |  Size: 15KB Width: 640  |  Height: 1136  |  Size: 15KB

+ 0
- 72
examples/DemoChanges.txt View File

@@ -1,72 +0,0 @@

AnimationComponent template:

base class for constantly repainting window.

member variables for getElapsedFrames() etc.



OPENGLComponent template:

methods for load / draw object.

3D Camera object and mousehandling.



AudioTemplate

simplest waveform drawing of input.


07719784(0)995




DEMO CHANGES:

Sidebar:
dark grey background white text;

Welcome:
Bouncy logo
Colours

Animation:
background (to texture/dark grey)
content

Code Editor:
dark grey background, white text

Dialog Boxes:
replace aluminium with texture background

MDI:
replace aluminium with texture background

Multi-touch:
darker grey background

Transforms:
replace aluminium with texture background

Windows:
texture background

2D Rendering:
Fonts:
Image formats:
Settings:
FilePlayback:
Latency detector:
Recording:
Synthesisers:
MIDI i/o:
Cryptography:
HTTP:
Multithreading:
XML & JSON:
replace aluminium with texture background

+ 27
- 0
examples/OpenGLAppExample/Builds/MacOSX/Info.plist View File

@@ -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>

+ 2134
- 0
examples/OpenGLAppExample/Builds/MacOSX/OpenGLAppExample.xcodeproj/project.pbxproj
File diff suppressed because it is too large
View File


BIN
examples/OpenGLAppExample/Builds/MacOSX/RecentFilesMenuTemplate.nib View File


+ 19
- 0
examples/OpenGLAppExample/Builds/VisualStudio2010/OpenGLAppExample.sln View File

@@ -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

+ 1703
- 0
examples/OpenGLAppExample/Builds/VisualStudio2010/OpenGLAppExample.vcxproj
File diff suppressed because it is too large
View File


+ 2918
- 0
examples/OpenGLAppExample/Builds/VisualStudio2010/OpenGLAppExample.vcxproj.filters
File diff suppressed because it is too large
View File


+ 29
- 0
examples/OpenGLAppExample/Builds/VisualStudio2010/resources.rc View File

@@ -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

+ 29
- 0
examples/OpenGLAppExample/Builds/iOS/Info.plist View File

@@ -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>

+ 2124
- 0
examples/OpenGLAppExample/Builds/iOS/OpenGLAppExample.xcodeproj/project.pbxproj
File diff suppressed because it is too large
View File


+ 58
- 0
examples/OpenGLAppExample/Builds/iOS/OpenGLAppExample/Images.xcassets/AppIcon.appiconset/Contents.json View File

@@ -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"
}
}

+ 50
- 0
examples/OpenGLAppExample/Builds/iOS/OpenGLAppExample/Images.xcassets/LaunchImage.launchimage/Contents.json View File

@@ -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"
}
}

+ 196
- 0
examples/OpenGLAppExample/JuceLibraryCode/AppConfig.h View File

@@ -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__

+ 1191
- 0
examples/OpenGLAppExample/JuceLibraryCode/BinaryData.cpp
File diff suppressed because it is too large
View File


+ 26
- 0
examples/OpenGLAppExample/JuceLibraryCode/BinaryData.h View File

@@ -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

+ 47
- 0
examples/OpenGLAppExample/JuceLibraryCode/JuceHeader.h View File

@@ -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__

+ 12
- 0
examples/OpenGLAppExample/JuceLibraryCode/ReadMe.txt View File

@@ -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).

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_audio_basics/juce_audio_basics.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_audio_devices/juce_audio_devices.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_audio_formats/juce_audio_formats.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_core/juce_core.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_cryptography/juce_cryptography.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_data_structures/juce_data_structures.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_events/juce_events.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_graphics/juce_graphics.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_gui_basics/juce_gui_basics.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_opengl/juce_opengl.h View File

@@ -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"

+ 5
- 0
examples/OpenGLAppExample/JuceLibraryCode/modules/juce_video/juce_video.h View File

@@ -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"

+ 111
- 0
examples/OpenGLAppExample/OpenGLAppExample.jucer View File

@@ -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>

+ 10
- 0
examples/OpenGLAppExample/Source/FragmentShader.glsl View File

@@ -0,0 +1,10 @@
/*
==============================================================================
FragmentShader.cpp
Created: 11 Nov 2014 12:17:53pm
Author: Felix Faire
==============================================================================
*/

+ 102
- 0
examples/OpenGLAppExample/Source/Main.cpp View File

@@ -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)

+ 403
- 0
examples/OpenGLAppExample/Source/MainComponent.cpp View File

@@ -0,0 +1,403 @@
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#ifndef MAINCOMPONENT_H_INCLUDED
#define MAINCOMPONENT_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
#include "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
{
setShaders();
}
void shutdown() override
{
shader = nullptr;
shape = nullptr;
attributes = nullptr;
uniforms = nullptr;
}
Matrix3D<float> getProjectionMatrix() const
{
float w = 1.0f / (0.5 + 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));
//viewMatrix *= draggableOrientation.getRotationMatrix();
// Matrix3D<float> rotationMatrix = viewMatrix.rotated (Vector3D<float> (rotation, rotation, -0.3f));
Matrix3D<float> rotationMatrix = viewMatrix.rotated (Vector3D<float> (-0.3f, 5.0f*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.1));
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_LESS);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
openGLContext.extensions.glActiveTexture (GL_TEXTURE0);
glEnable (GL_TEXTURE_2D);
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.drawEllipse (100, 100, 50, 50, 2);
}
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 setShaders()
{
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.8);\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:
//==============================================================================
// private member variables
struct Vertex
{
float position[3];
float normal[3];
float colour[4];
float texCoord[2];
};
//==============================================================================
// This class just manages the attributes that the demo 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");
texture = createUniform (openGLContext, shader, "demoTexture");
lightPosition = createUniform (openGLContext, shader, "lightPosition");
bouncingNumber = createUniform (openGLContext, shader, "bouncingNumber");
}
ScopedPointer<OpenGLShaderProgram::Uniform> projectionMatrix, viewMatrix, texture, lightPosition, bouncingNumber;
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

+ 359
- 0
examples/OpenGLAppExample/Source/Resources/WavefrontObjParser.h View File

@@ -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)
};

+ 2866
- 0
examples/OpenGLAppExample/Source/Resources/teapot.obj
File diff suppressed because it is too large
View File


+ 9
- 0
examples/OpenGLAppExample/Source/VertexShader.glsl View File

@@ -0,0 +1,9 @@
/*
==============================================================================
VertexShader.cpp
Created: 11 Nov 2014 12:17:40pm
Author: Felix Faire
==============================================================================
*/

+ 2
- 2
extras/Introjucer/JuceLibraryCode/BinaryData.cpp View File

@@ -716,10 +716,10 @@ static const unsigned char temp_binary_data_8[] =
"\r\n"
"void CONTENTCOMPCLASS::paint (Graphics& g)\r\n"
"{\r\n"
" g.fillAll (Colour (0xffeeddff));\r\n"
" g.fillAll (Colour (0xff001F36));\r\n"
"\r\n"
" g.setFont (Font (16.0f));\r\n"
" g.setColour (Colours::black);\r\n"
" g.setColour (Colours::white);\r\n"
" g.drawText (\"Hello World!\", getLocalBounds(), Justification::centred, true);\r\n"
"}\r\n"
"\r\n"


+ 2
- 2
extras/Introjucer/Source/BinaryData/jucer_ContentCompTemplate.cpp View File

@@ -21,10 +21,10 @@ CONTENTCOMPCLASS::~CONTENTCOMPCLASS()
void CONTENTCOMPCLASS::paint (Graphics& g)
{
g.fillAll (Colour (0xffeeddff));
g.fillAll (Colour (0xff001F36));
g.setFont (Font (16.0f));
g.setColour (Colours::black);
g.setColour (Colours::white);
g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true);
}


+ 0
- 77
extras/Introjucer/Source/BinaryData/jucer_OpenGLComponentTemplate.cpp View File

@@ -1,77 +0,0 @@
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#ifndef MAINCOMPONENT_H_INCLUDED
#define MAINCOMPONENT_H_INCLUDED
INCLUDE_JUCE
//==============================================================================
/*
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
{
}
void shutdown() override
{
}
void render() override
{
}
void paint (Graphics& g) override
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (Colours::black);
// You can add your drawing code here!
}
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.
}
private:
//==============================================================================
// private member variables
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

+ 4
- 5
extras/Introjucer/Source/BinaryData/jucer_OpenglComponentTemplate.cpp View File

@@ -40,15 +40,14 @@ public:
void render() override
{
OpenGLHelpers::clear (Colours::black);
}
void paint (Graphics& g) override
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (Colours::black);
// You can add your drawing code here!
// You can add your component specific drawing code here!
// This will draw over the top of the openGL background.
}
void resized() override


+ 0
- 698
modules/juce_box2d/box2d/Collision/b2CollideEdge.cpp View File

@@ -1,698 +0,0 @@
/*
* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "b2Collision.h"
#include "Shapes/b2CircleShape.h"
#include "Shapes/b2EdgeShape.h"
#include "Shapes/b2PolygonShape.h"
// Compute contact points for edge versus circle.
// This accounts for edge connectivity.
void b2CollideEdgeAndCircle(b2Manifold* manifold,
const b2EdgeShape* edgeA, const b2Transform& xfA,
const b2CircleShape* circleB, const b2Transform& xfB)
{
manifold->pointCount = 0;
// Compute circle in frame of edge
b2Vec2 Q = b2MulT(xfA, b2Mul(xfB, circleB->m_p));
b2Vec2 A = edgeA->m_vertex1, B = edgeA->m_vertex2;
b2Vec2 e = B - A;
// Barycentric coordinates
float32 u = b2Dot(e, B - Q);
float32 v = b2Dot(e, Q - A);
float32 radius = edgeA->m_radius + circleB->m_radius;
b2ContactFeature cf;
cf.indexB = 0;
cf.typeB = b2ContactFeature::e_vertex;
// Region A
if (v <= 0.0f)
{
b2Vec2 P = A;
b2Vec2 d = Q - P;
float32 dd = b2Dot(d, d);
if (dd > radius * radius)
{
return;
}
// Is there an edge connected to A?
if (edgeA->m_hasVertex0)
{
b2Vec2 A1 = edgeA->m_vertex0;
b2Vec2 B1 = A;
b2Vec2 e1 = B1 - A1;
float32 u1 = b2Dot(e1, B1 - Q);
// Is the circle in Region AB of the previous edge?
if (u1 > 0.0f)
{
return;
}
}
cf.indexA = 0;
cf.typeA = b2ContactFeature::e_vertex;
manifold->pointCount = 1;
manifold->type = b2Manifold::e_circles;
manifold->localNormal.SetZero();
manifold->localPoint = P;
manifold->points[0].id.key = 0;
manifold->points[0].id.cf = cf;
manifold->points[0].localPoint = circleB->m_p;
return;
}
// Region B
if (u <= 0.0f)
{
b2Vec2 P = B;
b2Vec2 d = Q - P;
float32 dd = b2Dot(d, d);
if (dd > radius * radius)
{
return;
}
// Is there an edge connected to B?
if (edgeA->m_hasVertex3)
{
b2Vec2 B2 = edgeA->m_vertex3;
b2Vec2 A2 = B;
b2Vec2 e2 = B2 - A2;
float32 v2 = b2Dot(e2, Q - A2);
// Is the circle in Region AB of the next edge?
if (v2 > 0.0f)
{
return;
}
}
cf.indexA = 1;
cf.typeA = b2ContactFeature::e_vertex;
manifold->pointCount = 1;
manifold->type = b2Manifold::e_circles;
manifold->localNormal.SetZero();
manifold->localPoint = P;
manifold->points[0].id.key = 0;
manifold->points[0].id.cf = cf;
manifold->points[0].localPoint = circleB->m_p;
return;
}
// Region AB
float32 den = b2Dot(e, e);
b2Assert(den > 0.0f);
b2Vec2 P = (1.0f / den) * (u * A + v * B);
b2Vec2 d = Q - P;
float32 dd = b2Dot(d, d);
if (dd > radius * radius)
{
return;
}
b2Vec2 n(-e.y, e.x);
if (b2Dot(n, Q - A) < 0.0f)
{
n.Set(-n.x, -n.y);
}
n.Normalize();
cf.indexA = 0;
cf.typeA = b2ContactFeature::e_face;
manifold->pointCount = 1;
manifold->type = b2Manifold::e_faceA;
manifold->localNormal = n;
manifold->localPoint = A;
manifold->points[0].id.key = 0;
manifold->points[0].id.cf = cf;
manifold->points[0].localPoint = circleB->m_p;
}
// This structure is used to keep track of the best separating axis.
struct b2EPAxis
{
enum Type
{
e_unknown,
e_edgeA,
e_edgeB
};
Type type;
int32 index;
float32 separation;
};
// This holds polygon B expressed in frame A.
struct b2TempPolygon
{
b2Vec2 vertices[b2_maxPolygonVertices];
b2Vec2 normals[b2_maxPolygonVertices];
int32 count;
};
// Reference face used for clipping
struct b2ReferenceFace
{
int32 i1, i2;
b2Vec2 v1, v2;
b2Vec2 normal;
b2Vec2 sideNormal1;
float32 sideOffset1;
b2Vec2 sideNormal2;
float32 sideOffset2;
};
// This class collides and edge and a polygon, taking into account edge adjacency.
struct b2EPCollider
{
void Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
const b2PolygonShape* polygonB, const b2Transform& xfB);
b2EPAxis ComputeEdgeSeparation();
b2EPAxis ComputePolygonSeparation();
enum VertexType
{
e_isolated,
e_concave,
e_convex
};
b2TempPolygon m_polygonB;
b2Transform m_xf;
b2Vec2 m_centroidB;
b2Vec2 m_v0, m_v1, m_v2, m_v3;
b2Vec2 m_normal0, m_normal1, m_normal2;
b2Vec2 m_normal;
VertexType m_type1, m_type2;
b2Vec2 m_lowerLimit, m_upperLimit;
float32 m_radius;
bool m_front;
};
// Algorithm:
// 1. Classify v1 and v2
// 2. Classify polygon centroid as front or back
// 3. Flip normal if necessary
// 4. Initialize normal range to [-pi, pi] about face normal
// 5. Adjust normal range according to adjacent edges
// 6. Visit each separating axes, only accept axes within the range
// 7. Return if _any_ axis indicates separation
// 8. Clip
void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
const b2PolygonShape* polygonB, const b2Transform& xfB)
{
m_xf = b2MulT(xfA, xfB);
m_centroidB = b2Mul(m_xf, polygonB->m_centroid);
m_v0 = edgeA->m_vertex0;
m_v1 = edgeA->m_vertex1;
m_v2 = edgeA->m_vertex2;
m_v3 = edgeA->m_vertex3;
bool hasVertex0 = edgeA->m_hasVertex0;
bool hasVertex3 = edgeA->m_hasVertex3;
b2Vec2 edge1 = m_v2 - m_v1;
edge1.Normalize();
m_normal1.Set(edge1.y, -edge1.x);
float32 offset1 = b2Dot(m_normal1, m_centroidB - m_v1);
float32 offset0 = 0.0f, offset2 = 0.0f;
bool convex1 = false, convex2 = false;
// Is there a preceding edge?
if (hasVertex0)
{
b2Vec2 edge0 = m_v1 - m_v0;
edge0.Normalize();
m_normal0.Set(edge0.y, -edge0.x);
convex1 = b2Cross(edge0, edge1) >= 0.0f;
offset0 = b2Dot(m_normal0, m_centroidB - m_v0);
}
// Is there a following edge?
if (hasVertex3)
{
b2Vec2 edge2 = m_v3 - m_v2;
edge2.Normalize();
m_normal2.Set(edge2.y, -edge2.x);
convex2 = b2Cross(edge1, edge2) > 0.0f;
offset2 = b2Dot(m_normal2, m_centroidB - m_v2);
}
// Determine front or back collision. Determine collision normal limits.
if (hasVertex0 && hasVertex3)
{
if (convex1 && convex2)
{
m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = m_normal0;
m_upperLimit = m_normal2;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = -m_normal1;
m_upperLimit = -m_normal1;
}
}
else if (convex1)
{
m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = m_normal0;
m_upperLimit = m_normal1;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = -m_normal2;
m_upperLimit = -m_normal1;
}
}
else if (convex2)
{
m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = m_normal1;
m_upperLimit = m_normal2;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = -m_normal1;
m_upperLimit = -m_normal0;
}
}
else
{
m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = m_normal1;
m_upperLimit = m_normal1;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = -m_normal2;
m_upperLimit = -m_normal0;
}
}
}
else if (hasVertex0)
{
if (convex1)
{
m_front = offset0 >= 0.0f || offset1 >= 0.0f;
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = m_normal0;
m_upperLimit = -m_normal1;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = m_normal1;
m_upperLimit = -m_normal1;
}
}
else
{
m_front = offset0 >= 0.0f && offset1 >= 0.0f;
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = m_normal1;
m_upperLimit = -m_normal1;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = m_normal1;
m_upperLimit = -m_normal0;
}
}
}
else if (hasVertex3)
{
if (convex2)
{
m_front = offset1 >= 0.0f || offset2 >= 0.0f;
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = -m_normal1;
m_upperLimit = m_normal2;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = -m_normal1;
m_upperLimit = m_normal1;
}
}
else
{
m_front = offset1 >= 0.0f && offset2 >= 0.0f;
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = -m_normal1;
m_upperLimit = m_normal1;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = -m_normal2;
m_upperLimit = m_normal1;
}
}
}
else
{
m_front = offset1 >= 0.0f;
if (m_front)
{
m_normal = m_normal1;
m_lowerLimit = -m_normal1;
m_upperLimit = -m_normal1;
}
else
{
m_normal = -m_normal1;
m_lowerLimit = m_normal1;
m_upperLimit = m_normal1;
}
}
// Get polygonB in frameA
m_polygonB.count = polygonB->m_vertexCount;
for (int32 i = 0; i < polygonB->m_vertexCount; ++i)
{
m_polygonB.vertices[i] = b2Mul(m_xf, polygonB->m_vertices[i]);
m_polygonB.normals[i] = b2Mul(m_xf.q, polygonB->m_normals[i]);
}
m_radius = 2.0f * b2_polygonRadius;
manifold->pointCount = 0;
b2EPAxis edgeAxis = ComputeEdgeSeparation();
// If no valid normal can be found than this edge should not collide.
if (edgeAxis.type == b2EPAxis::e_unknown)
{
return;
}
if (edgeAxis.separation > m_radius)
{
return;
}
b2EPAxis polygonAxis = ComputePolygonSeparation();
if (polygonAxis.type != b2EPAxis::e_unknown && polygonAxis.separation > m_radius)
{
return;
}
// Use hysteresis for jitter reduction.
const float32 k_relativeTol = 0.98f;
const float32 k_absoluteTol = 0.001f;
b2EPAxis primaryAxis;
if (polygonAxis.type == b2EPAxis::e_unknown)
{
primaryAxis = edgeAxis;
}
else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol)
{
primaryAxis = polygonAxis;
}
else
{
primaryAxis = edgeAxis;
}
b2ClipVertex ie[2];
b2ReferenceFace rf;
if (primaryAxis.type == b2EPAxis::e_edgeA)
{
manifold->type = b2Manifold::e_faceA;
// Search for the polygon normal that is most anti-parallel to the edge normal.
int32 bestIndex = 0;
float32 bestValue = b2Dot(m_normal, m_polygonB.normals[0]);
for (int32 i = 1; i < m_polygonB.count; ++i)
{
float32 value = b2Dot(m_normal, m_polygonB.normals[i]);
if (value < bestValue)
{
bestValue = value;
bestIndex = i;
}
}
int32 i1 = bestIndex;
int32 i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0;
ie[0].v = m_polygonB.vertices[i1];
ie[0].id.cf.indexA = 0;
ie[0].id.cf.indexB = (uint8) i1;
ie[0].id.cf.typeA = b2ContactFeature::e_face;
ie[0].id.cf.typeB = b2ContactFeature::e_vertex;
ie[1].v = m_polygonB.vertices[i2];
ie[1].id.cf.indexA = 0;
ie[1].id.cf.indexB = (uint8) i2;
ie[1].id.cf.typeA = b2ContactFeature::e_face;
ie[1].id.cf.typeB = b2ContactFeature::e_vertex;
if (m_front)
{
rf.i1 = 0;
rf.i2 = 1;
rf.v1 = m_v1;
rf.v2 = m_v2;
rf.normal = m_normal1;
}
else
{
rf.i1 = 1;
rf.i2 = 0;
rf.v1 = m_v2;
rf.v2 = m_v1;
rf.normal = -m_normal1;
}
}
else
{
manifold->type = b2Manifold::e_faceB;
ie[0].v = m_v1;
ie[0].id.cf.indexA = 0;
ie[0].id.cf.indexB = (uint8) primaryAxis.index;
ie[0].id.cf.typeA = b2ContactFeature::e_vertex;
ie[0].id.cf.typeB = b2ContactFeature::e_face;
ie[1].v = m_v2;
ie[1].id.cf.indexA = 0;
ie[1].id.cf.indexB = (uint8) primaryAxis.index;
ie[1].id.cf.typeA = b2ContactFeature::e_vertex;
ie[1].id.cf.typeB = b2ContactFeature::e_face;
rf.i1 = primaryAxis.index;
rf.i2 = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0;
rf.v1 = m_polygonB.vertices[rf.i1];
rf.v2 = m_polygonB.vertices[rf.i2];
rf.normal = m_polygonB.normals[rf.i1];
}
rf.sideNormal1.Set(rf.normal.y, -rf.normal.x);
rf.sideNormal2 = -rf.sideNormal1;
rf.sideOffset1 = b2Dot(rf.sideNormal1, rf.v1);
rf.sideOffset2 = b2Dot(rf.sideNormal2, rf.v2);
// Clip incident edge against extruded edge1 side edges.
b2ClipVertex clipPoints1[2];
b2ClipVertex clipPoints2[2];
int32 np;
// Clip to box side 1
np = b2ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1);
if (np < b2_maxManifoldPoints)
{
return;
}
// Clip to negative box side 1
np = b2ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2);
if (np < b2_maxManifoldPoints)
{
return;
}
// Now clipPoints2 contains the clipped points.
if (primaryAxis.type == b2EPAxis::e_edgeA)
{
manifold->localNormal = rf.normal;
manifold->localPoint = rf.v1;
}
else
{
manifold->localNormal = polygonB->m_normals[rf.i1];
manifold->localPoint = polygonB->m_vertices[rf.i1];
}
int32 pointCount = 0;
for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
{
float32 separation;
separation = b2Dot(rf.normal, clipPoints2[i].v - rf.v1);
if (separation <= m_radius)
{
b2ManifoldPoint* cp = manifold->points + pointCount;
if (primaryAxis.type == b2EPAxis::e_edgeA)
{
cp->localPoint = b2MulT(m_xf, clipPoints2[i].v);
cp->id = clipPoints2[i].id;
}
else
{
cp->localPoint = clipPoints2[i].v;
cp->id.cf.typeA = clipPoints2[i].id.cf.typeB;
cp->id.cf.typeB = clipPoints2[i].id.cf.typeA;
cp->id.cf.indexA = clipPoints2[i].id.cf.indexB;
cp->id.cf.indexB = clipPoints2[i].id.cf.indexA;
}
++pointCount;
}
}
manifold->pointCount = pointCount;
}
b2EPAxis b2EPCollider::ComputeEdgeSeparation()
{
b2EPAxis axis;
axis.type = b2EPAxis::e_edgeA;
axis.index = m_front ? 0 : 1;
axis.separation = FLT_MAX;
for (int32 i = 0; i < m_polygonB.count; ++i)
{
float32 s = b2Dot(m_normal, m_polygonB.vertices[i] - m_v1);
if (s < axis.separation)
{
axis.separation = s;
}
}
return axis;
}
b2EPAxis b2EPCollider::ComputePolygonSeparation()
{
b2EPAxis axis;
axis.type = b2EPAxis::e_unknown;
axis.index = -1;
axis.separation = -FLT_MAX;
b2Vec2 perp(-m_normal.y, m_normal.x);
for (int32 i = 0; i < m_polygonB.count; ++i)
{
b2Vec2 n = -m_polygonB.normals[i];
float32 s1 = b2Dot(n, m_polygonB.vertices[i] - m_v1);
float32 s2 = b2Dot(n, m_polygonB.vertices[i] - m_v2);
float32 s = b2Min(s1, s2);
if (s > m_radius)
{
// No collision
axis.type = b2EPAxis::e_edgeB;
axis.index = i;
axis.separation = s;
return axis;
}
// Adjacency
if (b2Dot(n, perp) >= 0.0f)
{
if (b2Dot(n - m_upperLimit, m_normal) < -b2_angularSlop)
{
continue;
}
}
else
{
if (b2Dot(n - m_lowerLimit, m_normal) < -b2_angularSlop)
{
continue;
}
}
if (s > axis.separation)
{
axis.type = b2EPAxis::e_edgeB;
axis.index = i;
axis.separation = s;
}
}
return axis;
}
void b2CollideEdgeAndPolygon( b2Manifold* manifold,
const b2EdgeShape* edgeA, const b2Transform& xfA,
const b2PolygonShape* polygonB, const b2Transform& xfB)
{
b2EPCollider collider;
collider.Collide(manifold, edgeA, xfA, polygonB, xfB);
}

+ 0
- 249
modules/juce_box2d/box2d/Collision/b2Collision.cpp View File

@@ -1,249 +0,0 @@
/*
* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "b2Collision.h"
#include "b2Distance.h"
void b2WorldManifold::Initialize(const b2Manifold* manifold,
const b2Transform& xfA, float32 radiusA,
const b2Transform& xfB, float32 radiusB)
{
if (manifold->pointCount == 0)
{
return;
}
switch (manifold->type)
{
case b2Manifold::e_circles:
{
normal.Set(1.0f, 0.0f);
b2Vec2 pointA = b2Mul(xfA, manifold->localPoint);
b2Vec2 pointB = b2Mul(xfB, manifold->points[0].localPoint);
if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon)
{
normal = pointB - pointA;
normal.Normalize();
}
b2Vec2 cA = pointA + radiusA * normal;
b2Vec2 cB = pointB - radiusB * normal;
points[0] = 0.5f * (cA + cB);
}
break;
case b2Manifold::e_faceA:
{
normal = b2Mul(xfA.q, manifold->localNormal);
b2Vec2 planePoint = b2Mul(xfA, manifold->localPoint);
for (int32 i = 0; i < manifold->pointCount; ++i)
{
b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint);
b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal;
b2Vec2 cB = clipPoint - radiusB * normal;
points[i] = 0.5f * (cA + cB);
}
}
break;
case b2Manifold::e_faceB:
{
normal = b2Mul(xfB.q, manifold->localNormal);
b2Vec2 planePoint = b2Mul(xfB, manifold->localPoint);
for (int32 i = 0; i < manifold->pointCount; ++i)
{
b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint);
b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal;
b2Vec2 cA = clipPoint - radiusA * normal;
points[i] = 0.5f * (cA + cB);
}
// Ensure normal points from A to B.
normal = -normal;
}
break;
}
}
void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
const b2Manifold* manifold1, const b2Manifold* manifold2)
{
for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
{
state1[i] = b2_nullState;
state2[i] = b2_nullState;
}
// Detect persists and removes.
for (int32 i = 0; i < manifold1->pointCount; ++i)
{
b2ContactID id = manifold1->points[i].id;
state1[i] = b2_removeState;
for (int32 j = 0; j < manifold2->pointCount; ++j)
{
if (manifold2->points[j].id.key == id.key)
{
state1[i] = b2_persistState;
break;
}
}
}
// Detect persists and adds.
for (int32 i = 0; i < manifold2->pointCount; ++i)
{
b2ContactID id = manifold2->points[i].id;
state2[i] = b2_addState;
for (int32 j = 0; j < manifold1->pointCount; ++j)
{
if (manifold1->points[j].id.key == id.key)
{
state2[i] = b2_persistState;
break;
}
}
}
}
// From Real-time Collision Detection, p179.
bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const
{
float32 tmin = -b2_maxFloat;
float32 tmax = b2_maxFloat;
b2Vec2 p = input.p1;
b2Vec2 d = input.p2 - input.p1;
b2Vec2 absD = b2Abs(d);
b2Vec2 normal;
for (int32 i = 0; i < 2; ++i)
{
if (absD(i) < b2_epsilon)
{
// Parallel.
if (p(i) < lowerBound(i) || upperBound(i) < p(i))
{
return false;
}
}
else
{
float32 inv_d = 1.0f / d(i);
float32 t1 = (lowerBound(i) - p(i)) * inv_d;
float32 t2 = (upperBound(i) - p(i)) * inv_d;
// Sign of the normal vector.
float32 s = -1.0f;
if (t1 > t2)
{
b2Swap(t1, t2);
s = 1.0f;
}
// Push the min up
if (t1 > tmin)
{
normal.SetZero();
normal(i) = s;
tmin = t1;
}
// Pull the max down
tmax = b2Min(tmax, t2);
if (tmin > tmax)
{
return false;
}
}
}
// Does the ray start inside the box?
// Does the ray intersect beyond the max fraction?
if (tmin < 0.0f || input.maxFraction < tmin)
{
return false;
}
// Intersection.
output->fraction = tmin;
output->normal = normal;
return true;
}
// Sutherland-Hodgman clipping.
int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
const b2Vec2& normal, float32 offset, int32 vertexIndexA)
{
// Start with no output points
int32 numOut = 0;
// Calculate the distance of end points to the line
float32 distance0 = b2Dot(normal, vIn[0].v) - offset;
float32 distance1 = b2Dot(normal, vIn[1].v) - offset;
// If the points are behind the plane
if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];
if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];
// If the points are on different sides of the plane
if (distance0 * distance1 < 0.0f)
{
// Find intersection point of edge and plane
float32 interp = distance0 / (distance0 - distance1);
vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
// VertexA is hitting edgeB.
vOut[numOut].id.cf.indexA = (uint8) vertexIndexA;
vOut[numOut].id.cf.indexB = vIn[0].id.cf.indexB;
vOut[numOut].id.cf.typeA = b2ContactFeature::e_vertex;
vOut[numOut].id.cf.typeB = b2ContactFeature::e_face;
++numOut;
}
return numOut;
}
bool b2TestOverlap( const b2Shape* shapeA, int32 indexA,
const b2Shape* shapeB, int32 indexB,
const b2Transform& xfA, const b2Transform& xfB)
{
b2DistanceInput input;
input.proxyA.Set(shapeA, indexA);
input.proxyB.Set(shapeB, indexB);
input.transformA = xfA;
input.transformB = xfB;
input.useRadii = true;
b2SimplexCache cache;
cache.count = 0;
b2DistanceOutput output;
b2Distance(&output, &cache, &input);
return output.distance < 10.0f * b2_epsilon;
}

+ 0
- 947
modules/juce_browser_plugin_client/wrapper/juce_activex_gluecode.cpp View File

@@ -1,947 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found 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.juce.com for more information.
==============================================================================
*/
//==============================================================================
/*
This file contains all the gubbins to create an ActiveX browser plugin that
wraps your BrowserPluginComponent object.
*/
//==============================================================================
#if _MSC_VER
//==============================================================================
#include <olectl.h>
#include <objsafe.h>
#include <exdisp.h>
#pragma warning (disable:4584)
#include "../juce_browser_plugin.h"
using namespace juce;
#include "juce_BrowserPluginComponent.h"
#ifndef JuceBrowserPlugin_ActiveXCLSID
#error "For an activeX plugin, you need to define JuceBrowserPlugin_ActiveXCLSID in your BrowserPluginCharacteristics.h file!"
#endif
//==============================================================================
#if JUCE_DEBUG
static int numDOWID = 0, numJuceSO = 0;
#endif
#define log(a) DBG(a)
// Cunning trick used to add functions to export list without messing about with .def files.
#define EXPORTED_FUNCTION comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
//==============================================================================
static void juceVarToVariant (const var& v, VARIANT& dest);
static var variantTojuceVar (const VARIANT& v);
//==============================================================================
// Takes care of the logic in invoking var methods from IDispatch callbacks.
class IDispatchHelper
{
public:
IDispatchHelper() {}
String getStringFromDISPID (const DISPID hash) const
{
return identifierNames [identifierIDs.indexOf (hash)];
}
DISPID getDISPIDForName (const String& name)
{
const int i = identifierNames.indexOf (String (name));
if (i >= 0)
return identifierIDs[i];
const DISPID newID = (DISPID) name.hashCode64();
identifierNames.add (name);
identifierIDs.add (newID);
return newID;
}
HRESULT doGetIDsOfNames (LPOLESTR* rgszNames, UINT cNames, DISPID* rgDispId)
{
for (unsigned int i = 0; i < cNames; ++i)
rgDispId[i] = getDISPIDForName (rgszNames[i]);
return S_OK;
}
HRESULT doInvoke (const var& v,
DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
const Identifier memberId (getStringFromDISPID (dispIdMember));
DynamicObject* const object = v.getDynamicObject();
if (memberId.toString().isEmpty() || object == nullptr)
return DISP_E_MEMBERNOTFOUND;
if ((wFlags & DISPATCH_METHOD) != 0)
{
if (object->hasMethod (memberId))
{
const int numArgs = pDispParams == nullptr ? 0 : pDispParams->cArgs;
var result;
if (numArgs == 0)
{
result = v.call (memberId);
}
else
{
Array<var> args;
for (int j = numArgs; --j >= 0;)
args.add (variantTojuceVar (pDispParams->rgvarg[j]));
result = v.invoke (memberId, numArgs == 0 ? nullptr : args.getRawDataPointer(), numArgs);
}
if (pVarResult != nullptr)
juceVarToVariant (result, *pVarResult);
return S_OK;
}
}
else if ((wFlags & DISPATCH_PROPERTYGET) != 0)
{
if (object->hasProperty (memberId) && pVarResult != nullptr)
{
juceVarToVariant (object->getProperty (memberId), *pVarResult);
return S_OK;
}
}
else if ((wFlags & DISPATCH_PROPERTYPUT) != 0)
{
if (pDispParams != nullptr && pDispParams->cArgs > 0)
{
object->setProperty (memberId, variantTojuceVar (pDispParams->rgvarg[0]));
return S_OK;
}
}
return DISP_E_MEMBERNOTFOUND;
}
private:
Array<DISPID> identifierIDs;
StringArray identifierNames;
JUCE_DECLARE_NON_COPYABLE (IDispatchHelper)
};
//==============================================================================
// Makes a var look like an IDispatch
class IDispatchWrappingDynamicObject : public IDispatch
{
public:
IDispatchWrappingDynamicObject (const var& object_)
: object (object_),
refCount (1)
{
DBG ("num Juce wrapper objs: " + String (++numJuceSO));
}
virtual ~IDispatchWrappingDynamicObject()
{
DBG ("num Juce wrapper objs: " + String (--numJuceSO));
}
HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
{
if (id == IID_IUnknown) { AddRef(); *result = (IUnknown*) this; return S_OK; }
if (id == IID_IDispatch) { AddRef(); *result = (IDispatch*) this; return S_OK; }
*result = 0;
return E_NOINTERFACE;
}
ULONG __stdcall AddRef() { return ++refCount; }
ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
HRESULT __stdcall GetTypeInfoCount (UINT*) { return E_NOTIMPL; }
HRESULT __stdcall GetTypeInfo (UINT, LCID, ITypeInfo**) { return E_NOTIMPL; }
HRESULT __stdcall GetIDsOfNames (REFIID riid, LPOLESTR* rgszNames, UINT cNames,
LCID lcid, DISPID* rgDispId)
{
return iDispatchHelper.doGetIDsOfNames (rgszNames, cNames, rgDispId);
}
HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams, VARIANT* pVarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
return iDispatchHelper.doInvoke (object, dispIdMember, riid, lcid, wFlags, pDispParams,
pVarResult, pExcepInfo, puArgErr);
}
private:
//==============================================================================
var object;
int refCount;
IDispatchHelper iDispatchHelper;
JUCE_DECLARE_NON_COPYABLE (IDispatchWrappingDynamicObject)
};
//==============================================================================
// Makes an IDispatch look like a var
class DynamicObjectWrappingIDispatch : public DynamicObject
{
public:
DynamicObjectWrappingIDispatch (IDispatch* const source_)
: source (source_)
{
source->AddRef();
log ("num IDispatch wrapper objs: " + String (++numDOWID));
}
~DynamicObjectWrappingIDispatch()
{
source->Release();
log ("num IDispatch wrapper objs: " + String (--numDOWID));
}
var getProperty (const Identifier& propertyName) const override
{
const String nameCopy (propertyName.toString());
LPCOLESTR name = nameCopy.toUTF16();
DISPID id = 0;
if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK)
{
EXCEPINFO excepInfo;
DISPPARAMS params;
zerostruct (params);
UINT argError;
VARIANT result;
zerostruct (result);
if (source->Invoke (id, IID_NULL, 0, DISPATCH_PROPERTYGET,
&params, &result, &excepInfo, &argError) == S_OK)
{
var v (variantTojuceVar (result));
VariantClear (&result);
return v;
}
}
return var();
}
bool hasProperty (const Identifier& propertyName) const override
{
const String nameCopy (propertyName.toString());
LPCOLESTR name = nameCopy.toUTF16();
DISPID id = 0;
return source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK;
}
void setProperty (const Identifier& propertyName, const var& newValue) override
{
const String nameCopy (propertyName.toString());
LPCOLESTR name = nameCopy.toUTF16();
DISPID id = 0;
if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK)
{
VARIANT param;
zerostruct (param);
juceVarToVariant (newValue, param);
DISPPARAMS dispParams;
zerostruct (dispParams);
dispParams.cArgs = 1;
dispParams.rgvarg = &param;
EXCEPINFO excepInfo;
zerostruct (excepInfo);
VARIANT result;
zerostruct (result);
UINT argError = 0;
if (source->Invoke (id, IID_NULL, 0, DISPATCH_PROPERTYPUT,
&dispParams, &result, &excepInfo, &argError) == S_OK)
{
VariantClear (&result);
}
VariantClear (&param);
}
}
void removeProperty (const Identifier& propertyName) override
{
setProperty (propertyName, var());
}
bool hasMethod (const Identifier& methodName) const override
{
const String nameCopy (methodName.toString());
LPCOLESTR name = nameCopy.toUTF16();
DISPID id = 0;
return source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK;
}
var invokeMethod (Identifier methodName, const var::NativeFunctionArgs& args) override
{
var returnValue;
const String nameCopy (methodName.toString());
LPCOLESTR name = nameCopy.toUTF16();
DISPID id = 0;
if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK)
{
HeapBlock <VARIANT> params;
params.calloc (args.numArguments + 1);
for (int i = 0; i < args.numArguments; ++i)
juceVarToVariant (args.arguments[(args.numArguments - 1) - i], params[i]);
DISPPARAMS dispParams;
zerostruct (dispParams);
dispParams.cArgs = args.numArguments;
dispParams.rgvarg = params;
EXCEPINFO excepInfo;
zerostruct (excepInfo);
VARIANT result;
zerostruct (result);
UINT argError = 0;
if (source->Invoke (id, IID_NULL, 0, DISPATCH_METHOD,
&dispParams, &result, &excepInfo, &argError) == S_OK)
{
returnValue = variantTojuceVar (result);
VariantClear (&result);
}
}
return returnValue;
}
private:
IDispatch* const source;
JUCE_DECLARE_NON_COPYABLE (DynamicObjectWrappingIDispatch)
};
//==============================================================================
void juceVarToVariant (const var& v, VARIANT& dest)
{
if (v.isVoid())
{
dest.vt = VT_EMPTY;
}
else if (v.isInt())
{
dest.vt = VT_INT;
dest.intVal = (int) v;
}
else if (v.isBool())
{
dest.vt = VT_BOOL;
dest.boolVal = (int) v;
}
else if (v.isDouble())
{
dest.vt = VT_R8;
dest.dblVal = (double) v;
}
else if (v.isString())
{
dest.vt = VT_BSTR;
dest.bstrVal = SysAllocString (v.toString().toUTF16());
}
else if (v.getDynamicObject() != nullptr)
{
dest.vt = VT_DISPATCH;
dest.pdispVal = new IDispatchWrappingDynamicObject (v);
}
else if (v.isMethod())
{
dest.vt = VT_EMPTY;
}
}
var variantTojuceVar (const VARIANT& v)
{
if ((v.vt & VT_ARRAY) != 0)
{
//xxx
}
else
{
switch (v.vt & ~VT_BYREF)
{
case VT_VOID:
case VT_EMPTY: return var();
case VT_I1: return var ((int) v.cVal);
case VT_I2: return var ((int) v.iVal);
case VT_I4: return var ((int) v.lVal);
case VT_I8: return var (String (v.llVal));
case VT_UI1: return var ((int) v.bVal);
case VT_UI2: return var ((int) v.uiVal);
case VT_UI4: return var ((int) v.ulVal);
case VT_UI8: return var (String (v.ullVal));
case VT_INT: return var ((int) v.intVal);
case VT_UINT: return var ((int) v.uintVal);
case VT_R4: return var ((double) v.fltVal);
case VT_R8: return var ((double) v.dblVal);
case VT_BSTR: return var (String (v.bstrVal));
case VT_BOOL: return var (v.boolVal ? true : false);
case VT_DISPATCH: return var (new DynamicObjectWrappingIDispatch (v.pdispVal));
default: break;
}
}
return var();
}
//==============================================================================
// This acts as the embedded HWND
class AXBrowserPluginHolderComponent : public Component
{
public:
AXBrowserPluginHolderComponent()
: parentHWND (0),
browser (nullptr)
{
setOpaque (true);
setWantsKeyboardFocus (false);
addAndMakeVisible (child = createBrowserPlugin());
jassert (child != nullptr); // You have to create one of these!
}
~AXBrowserPluginHolderComponent()
{
setWindow (nullptr);
child = nullptr;
}
//==============================================================================
void paint (Graphics& g) override
{
if (child == nullptr || ! child->isOpaque())
g.fillAll (Colours::white);
}
void resized() override
{
if (child != nullptr)
child->setBounds (getLocalBounds());
}
var getObject() { return child->getJavascriptObject(); }
void setWindow (IOleInPlaceSite* site)
{
if (browser != nullptr)
{
browser->Release();
browser = nullptr;
}
HWND newHWND = 0;
if (site != nullptr)
{
site->GetWindow (&newHWND);
IServiceProvider* sp = nullptr;
site->QueryInterface (IID_IServiceProvider, (void**) &sp);
if (sp != nullptr)
{
sp->QueryService (IID_IWebBrowserApp, IID_IWebBrowser2, (void**) &browser);
sp->Release();
}
}
if (parentHWND != newHWND)
{
removeFromDesktop();
setVisible (false);
parentHWND = newHWND;
if (parentHWND != 0)
{
addToDesktop (0);
HWND ourHWND = (HWND) getWindowHandle();
SetParent (ourHWND, parentHWND);
DWORD val = GetWindowLong (ourHWND, GWL_STYLE);
val = (val & ~WS_POPUP) | WS_CHILD;
SetWindowLong (ourHWND, GWL_STYLE, val);
setVisible (true);
}
}
if (site != nullptr)
site->OnInPlaceActivate();
}
String getBrowserURL() const
{
if (browser == nullptr)
return String::empty;
BSTR url = nullptr;
browser->get_LocationURL (&url);
return URL::removeEscapeChars (url);
}
private:
//==============================================================================
ScopedPointer<BrowserPluginComponent> child;
HWND parentHWND;
IWebBrowser2* browser;
JUCE_DECLARE_NON_COPYABLE (AXBrowserPluginHolderComponent)
};
//==============================================================================
extern String browserVersionDesc;
static String getExePath()
{
TCHAR moduleFile [2048] = { 0 };
GetModuleFileName (0, moduleFile, 2048);
return moduleFile;
}
static String getExeVersion (const String& exeFileName, const String& fieldName)
{
DWORD pointlessWin32Variable;
DWORD size = GetFileVersionInfoSize (exeFileName.toUTF16(), &pointlessWin32Variable);
if (size > 0)
{
HeapBlock <char> exeInfo;
exeInfo.calloc (size);
if (GetFileVersionInfo (exeFileName.toUTF16(), 0, size, exeInfo))
{
TCHAR* result = nullptr;
unsigned int resultLen = 0;
// try the 1200 codepage (Unicode)
String queryStr ("\\StringFileInfo\\040904B0\\" + fieldName);
if (! VerQueryValue (exeInfo, (LPTSTR) queryStr.toUTF16().getAddress(), (void**) &result, &resultLen))
{
// try the 1252 codepage (Windows Multilingual)
queryStr = "\\StringFileInfo\\040904E4\\" + fieldName;
VerQueryValue (exeInfo, (LPTSTR) queryStr.toUTF16().getAddress(), (void**) &result, &resultLen);
}
return String (result, resultLen);
}
}
return String::empty;
}
static int numActivePlugins = 0;
class JuceActiveXObject : public IUnknown,
public IDispatch,
public IObjectWithSite,
public IObjectSafety,
public IOleInPlaceObject
{
public:
JuceActiveXObject()
: site (nullptr), refCount (0)
{
log ("JuceActiveXObject");
}
~JuceActiveXObject()
{
log ("~JuceActiveXObject");
holderComp = nullptr;
}
HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
{
if (id == IID_IUnknown) { AddRef(); *result = (IUnknown*) this; return S_OK; }
if (id == IID_IDispatch) { AddRef(); *result = (IDispatch*) this; return S_OK; }
if (id == IID_IObjectWithSite) { AddRef(); *result = (IObjectWithSite*) this; return S_OK; }
if (id == IID_IObjectSafety) { AddRef(); *result = (IObjectSafety*) this; return S_OK; }
if (id == IID_IOleInPlaceObject) { AddRef(); *result = (IOleInPlaceObject*) this; return S_OK; }
if (id == IID_IOleWindow) { AddRef(); *result = (IOleWindow*) (IOleInPlaceObject*) this; return S_OK; }
*result = 0;
return E_NOINTERFACE;
}
ULONG __stdcall AddRef() { return ++refCount; }
ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
HRESULT __stdcall GetTypeInfoCount (UINT* pctinfo) { return E_NOTIMPL; }
HRESULT __stdcall GetTypeInfo (UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { return E_NOTIMPL; }
HRESULT __stdcall GetIDsOfNames (REFIID riid, LPOLESTR* rgszNames, UINT cNames,
LCID lcid, DISPID* rgDispId)
{
return iDispatchHelper.doGetIDsOfNames (rgszNames, cNames, rgDispId);
}
HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams, VARIANT* pVarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
if (holderComp == nullptr)
return DISP_E_MEMBERNOTFOUND;
return iDispatchHelper.doInvoke (holderComp->getObject(),
dispIdMember, riid, lcid, wFlags, pDispParams,
pVarResult, pExcepInfo, puArgErr);
}
HRESULT __stdcall SetSite (IUnknown* newSite)
{
if (newSite != site)
{
if (site != nullptr)
site->Release();
site = newSite;
if (site != nullptr)
{
site->AddRef();
IOleInPlaceSite* inPlaceSite = nullptr;
site->QueryInterface (IID_IOleInPlaceSite, (void**) &inPlaceSite);
if (inPlaceSite != nullptr)
{
createHolderComp();
holderComp->setWindow (inPlaceSite);
inPlaceSite->Release();
}
else
{
deleteHolderComp();
}
}
else
{
deleteHolderComp();
}
}
return S_OK;
}
void createHolderComp()
{
if (holderComp == nullptr)
{
if (numActivePlugins++ == 0)
{
log ("initialiseJuce_GUI()");
initialiseJuce_GUI();
browserVersionDesc = "Internet Explorer " + getExeVersion (getExePath(), "FileVersion");
}
holderComp = new AXBrowserPluginHolderComponent();
}
}
void deleteHolderComp()
{
if (holderComp != nullptr)
{
holderComp = nullptr;
if (--numActivePlugins == 0)
{
log ("shutdownJuce_GUI()");
shutdownJuce_GUI();
}
}
}
HRESULT __stdcall GetSite (REFIID riid, void **ppvSite)
{
*ppvSite = site;
return S_OK;
}
//==============================================================================
HRESULT __stdcall SetObjectRects (LPCRECT r, LPCRECT c)
{
if (holderComp != nullptr)
holderComp->setBounds (r->left, r->top, r->right - r->left, r->bottom - r->top);
return S_OK;
}
HRESULT __stdcall GetWindow (HWND* phwnd)
{
if (holderComp == nullptr)
return E_NOTIMPL;
*phwnd = (HWND) holderComp->getWindowHandle();
return S_OK;
}
//==============================================================================
HRESULT __stdcall ContextSensitiveHelp (BOOL fEnterMode) { return E_NOTIMPL; }
HRESULT __stdcall InPlaceDeactivate() { return E_NOTIMPL; }
HRESULT __stdcall UIDeactivate() { return E_NOTIMPL; }
HRESULT __stdcall ReactivateAndUndo() { return E_NOTIMPL; }
//==============================================================================
HRESULT __stdcall GetInterfaceSafetyOptions (REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
{
*pdwSupportedOptions = *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA;
return S_OK;
}
HRESULT __stdcall SetInterfaceSafetyOptions (REFIID, DWORD, DWORD) { return S_OK; }
private:
IUnknown* site;
int refCount;
ScopedPointer<AXBrowserPluginHolderComponent> holderComp;
IDispatchHelper iDispatchHelper;
JUCE_DECLARE_NON_COPYABLE (JuceActiveXObject)
};
//==============================================================================
class JuceActiveXObjectFactory : public IUnknown,
public IClassFactory
{
public:
JuceActiveXObjectFactory() : refCount (0) {}
HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
{
if (id == IID_IUnknown) { AddRef(); *result = (IUnknown*) this; return S_OK; }
if (id == IID_IClassFactory) { AddRef(); *result = (IClassFactory*) this; return S_OK; }
*result = nullptr;
return E_NOINTERFACE;
}
ULONG __stdcall AddRef() { return ++refCount; }
ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; }
HRESULT __stdcall CreateInstance (IUnknown* pUnkOuter, REFIID riid, void** ppvObject)
{
*ppvObject = nullptr;
if (pUnkOuter != nullptr && riid != IID_IUnknown)
return CLASS_E_NOAGGREGATION;
JuceActiveXObject* ax = new JuceActiveXObject();
return ax->QueryInterface (riid, ppvObject);
}
HRESULT __stdcall LockServer (BOOL /*fLock*/) { return S_OK; }
private:
int refCount;
JUCE_DECLARE_NON_COPYABLE (JuceActiveXObjectFactory)
};
//==============================================================================
String getActiveXBrowserURL (const BrowserPluginComponent* comp)
{
if (AXBrowserPluginHolderComponent* ax = dynamic_cast<AXBrowserPluginHolderComponent*> (comp->getParentComponent()))
return ax->getBrowserURL();
return String();
}
//==============================================================================
extern "C" BOOL WINAPI DllMain (HANDLE instance, DWORD reason, LPVOID)
{
#pragma EXPORTED_FUNCTION
switch (reason)
{
case DLL_PROCESS_ATTACH:
log ("DLL_PROCESS_ATTACH");
Process::setCurrentModuleInstanceHandle (instance);
break;
case DLL_PROCESS_DETACH:
log ("DLL_PROCESS_DETACH");
browserVersionDesc.clear();
// IE has a tendency to leak our objects, so although none of this should be
// necessary, it's best to make sure..
jassert (numActivePlugins == 0);
shutdownJuce_GUI();
break;
default:
break;
}
return TRUE;
}
static String CLSIDToJuceString (REFCLSID clsid)
{
LPWSTR s = nullptr;
StringFromIID (clsid, &s);
if (s == nullptr)
return String::empty;
const String result (s);
LPMALLOC malloc;
CoGetMalloc (1, &malloc);
if (malloc != nullptr)
{
malloc->Free (s);
malloc->Release();
}
return result.removeCharacters ("{}").trim();
}
STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
#pragma EXPORTED_FUNCTION
*ppv = nullptr;
if (CLSIDToJuceString (rclsid).equalsIgnoreCase (String (JuceBrowserPlugin_ActiveXCLSID)))
{
JuceActiveXObjectFactory* afx = new JuceActiveXObjectFactory();
if (afx->QueryInterface (riid, ppv) == S_OK)
return S_OK;
delete afx;
}
return CLASS_E_CLASSNOTAVAILABLE;
}
STDAPI DllCanUnloadNow()
{
#pragma EXPORTED_FUNCTION
return S_OK;
}
//==============================================================================
static String makeLegalRegistryName (const String& s)
{
return s.retainCharacters ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.");
}
static HRESULT doRegistration (const bool unregister)
{
const String company (makeLegalRegistryName (JuceBrowserPlugin_Company));
const String plugin (makeLegalRegistryName (JuceBrowserPlugin_Name));
const String clsID ("{" + String (JuceBrowserPlugin_ActiveXCLSID).toUpperCase() + "}");
const String root ("HKEY_CLASSES_ROOT\\");
const String companyDotPlugin (company + "." + plugin);
const String companyDotPluginCur (companyDotPlugin + ".1");
const String clsIDRoot (root + "CLSID\\" + clsID + "\\");
const String dllPath (File::getSpecialLocation (File::currentApplicationFile).getFullPathName());
StringPairArray settings;
settings.set (root + companyDotPluginCur + "\\", JuceBrowserPlugin_Name);
settings.set (root + companyDotPluginCur + "\\CLSID\\", clsID);
settings.set (root + companyDotPlugin + "\\", JuceBrowserPlugin_Name);
settings.set (root + companyDotPlugin + "\\CLSID\\", clsID);
settings.set (root + companyDotPlugin + "\\CurVer\\", companyDotPluginCur);
settings.set (clsIDRoot, JuceBrowserPlugin_Name);
settings.set (clsIDRoot + "Implemented Categories\\{7DD95801-9882-11CF-9FA9-00AA006C42C4}\\", String::empty);
settings.set (clsIDRoot + "Implemented Categories\\{7DD95802-9882-11CF-9FA9-00AA006C42C4}\\", String::empty);
settings.set (clsIDRoot + "ProgID\\", companyDotPluginCur);
settings.set (clsIDRoot + "VersionIndependentProgID\\", companyDotPlugin);
settings.set (clsIDRoot + "Programmable\\", String::empty);
settings.set (clsIDRoot + "InProcServer32\\", dllPath);
settings.set (clsIDRoot + "InProcServer32\\ThreadingModel", "Apartment");
settings.set (clsIDRoot + "Control\\", String::empty);
settings.set (clsIDRoot + "Insertable\\", String::empty);
settings.set (clsIDRoot + "ToolboxBitmap32\\", dllPath + ", 101");
settings.set (clsIDRoot + "TypeLib\\", "");
settings.set (clsIDRoot + "Version\\", JuceBrowserPlugin_Version);
if (unregister)
{
for (int i = 0; i < settings.getAllKeys().size(); ++i)
WindowsRegistry::deleteValue (settings.getAllKeys()[i]);
WindowsRegistry::deleteKey (root + companyDotPluginCur);
WindowsRegistry::deleteKey (root + companyDotPlugin);
WindowsRegistry::deleteKey (clsIDRoot);
if (WindowsRegistry::valueExists (clsIDRoot + "InProcServer32"))
return SELFREG_E_CLASS;
}
else
{
WindowsRegistry::deleteKey (clsIDRoot);
for (int i = 0; i < settings.getAllKeys().size(); ++i)
WindowsRegistry::setValue (settings.getAllKeys()[i],
settings [settings.getAllKeys()[i]]);
// check whether the registration actually worked - if not, we probably don't have
// enough privileges to write to the registry..
if (WindowsRegistry::getValue (clsIDRoot + "InProcServer32\\") != dllPath)
return SELFREG_E_CLASS;
}
return S_OK;
}
STDAPI DllRegisterServer()
{
#pragma EXPORTED_FUNCTION
return doRegistration (false);
}
STDAPI DllUnregisterServer()
{
#pragma EXPORTED_FUNCTION
return doRegistration (true);
}
#endif

+ 2
- 1
modules/juce_opengl/utils/juce_OpenGLAppComponent.h View File

@@ -62,10 +62,11 @@ public:
*/
virtual void render() = 0;
OpenGLContext openGLContext;
private:
//==============================================================================
OpenGLContext openGLContext;
int frameCounter;
void newOpenGLContextCreated() override;


Loading…
Cancel
Save