| @@ -65,14 +65,11 @@ public: | |||
| // we'll use the opportunity to create the textures needed. | |||
| void newOpenGLContextCreated() | |||
| { | |||
| texture1 = createImage1(); | |||
| texture2 = createImage2(); | |||
| // (no need to call makeCurrentContextActive(), as that will have | |||
| // been done for us before the method call). | |||
| glClearColor (0.0f, 0.0f, 0.0f, 0.0f); | |||
| #if ! JUCE_OPENGL_ES | |||
| glClearDepth (1.0); | |||
| #endif | |||
| glDepthFunc (GL_LESS); | |||
| glEnable (GL_DEPTH_TEST); | |||
| glEnable (GL_TEXTURE_2D); | |||
| @@ -82,9 +79,6 @@ public: | |||
| glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); | |||
| glHint (GL_POINT_SMOOTH_HINT, GL_NICEST); | |||
| glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
| texture1.load (createImage1()); | |||
| texture2.load (createImage2()); | |||
| } | |||
| void mouseDrag (const MouseEvent& e) | |||
| @@ -96,37 +90,34 @@ public: | |||
| void renderOpenGL() | |||
| { | |||
| OpenGLHelpers::clear (Colours::darkgrey.withAlpha (0.0f)); | |||
| OpenGLHelpers::prepareFor2D (getWidth(), getHeight()); | |||
| OpenGLHelpers::clear (Colours::darkblue); | |||
| glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |||
| glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |||
| OpenGLHelpers::prepareFor2D (getWidth(), getHeight()); | |||
| OpenGLFrameBuffer& frameBuffer1 = dynamic_cast <OpenGLFrameBufferImage*> (texture1.getSharedImage())->frameBuffer; | |||
| OpenGLFrameBuffer& frameBuffer2 = dynamic_cast <OpenGLFrameBufferImage*> (texture2.getSharedImage())->frameBuffer; | |||
| texture1.draw2D (50.0f, getHeight() - 50.0f, | |||
| getWidth() - 50.0f, getHeight() - 50.0f, | |||
| getWidth() - 50.0f, 50.0f, | |||
| 50.0f, 50.0f, | |||
| Colours::white.withAlpha (fabsf (::sinf (rotation / 100.0f)))); | |||
| frameBuffer1.draw2D (50.0f, getHeight() - 50.0f, | |||
| getWidth() - 50.0f, getHeight() - 50.0f, | |||
| getWidth() - 50.0f, 50.0f, | |||
| 50.0f, 50.0f, | |||
| Colours::white.withAlpha (fabsf (::sinf (rotation / 100.0f)))); | |||
| glLoadIdentity(); | |||
| glClear (GL_DEPTH_BUFFER_BIT); | |||
| OpenGLHelpers::setPerspective (45.0, getWidth() / (double) getHeight(), 0.1, 100.0); | |||
| glMatrixMode (GL_MODELVIEW); | |||
| glPushMatrix(); | |||
| glTranslatef (0.0f, 0.0f, -5.0f); | |||
| glRotatef (rotation, 0.5f, 1.0f, 0.0f); | |||
| // this draws the sides of our spinning cube.. | |||
| texture1.draw3D (-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, Colours::white); | |||
| texture1.draw3D (-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, Colours::white); | |||
| texture1.draw3D (-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, Colours::white); | |||
| texture2.draw3D (-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, Colours::white); | |||
| texture2.draw3D ( 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, Colours::white); | |||
| texture2.draw3D (-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, Colours::white); | |||
| glPopMatrix(); | |||
| frameBuffer1.draw3D (-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, Colours::white); | |||
| frameBuffer1.draw3D (-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, Colours::white); | |||
| frameBuffer1.draw3D (-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, Colours::white); | |||
| frameBuffer2.draw3D (-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, Colours::white); | |||
| frameBuffer2.draw3D ( 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, Colours::white); | |||
| frameBuffer2.draw3D (-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, Colours::white); | |||
| } | |||
| void timerCallback() | |||
| @@ -136,13 +127,13 @@ public: | |||
| } | |||
| private: | |||
| OpenGLTexture texture1, texture2; | |||
| Image texture1, texture2; | |||
| float rotation, delta; | |||
| // Functions to create a couple of images to use as textures.. | |||
| static Image createImage1() | |||
| { | |||
| Image image (Image::ARGB, 256, 256, true, Image::SoftwareImage); | |||
| Image image (new OpenGLFrameBufferImage (Image::ARGB, 256, 256)); | |||
| Graphics g (image); | |||
| @@ -150,12 +141,14 @@ private: | |||
| g.drawImageWithin (ImageFileFormat::loadFrom (BinaryData::juce_png, BinaryData::juce_pngSize), | |||
| 0, 0, image.getWidth(), image.getHeight(), RectanglePlacement::stretchToFit); | |||
| drawRandomStars (g, image.getWidth(), image.getHeight()); | |||
| return image; | |||
| } | |||
| static Image createImage2() | |||
| { | |||
| Image image (Image::ARGB, 128, 128, true, Image::SoftwareImage); | |||
| Image image (new OpenGLFrameBufferImage (Image::ARGB, 128, 128)); | |||
| Graphics g (image); | |||
| g.fillAll (Colours::darkred.withAlpha (0.7f)); | |||
| @@ -168,8 +161,22 @@ private: | |||
| true)); | |||
| g.fillPath (p); | |||
| drawRandomStars (g, image.getWidth(), image.getHeight()); | |||
| return image; | |||
| } | |||
| static void drawRandomStars (Graphics& g, int w, int h) | |||
| { | |||
| Random r; | |||
| for (int i = 10; --i >= 0;) | |||
| { | |||
| Path pp; | |||
| pp.addStar (Point<float> (r.nextInt (w), r.nextInt (h)), r.nextInt (8) + 3, 10, 20, 0); | |||
| g.setColour (Colours::pink.withAlpha (0.4f)); | |||
| g.fillPath (pp); | |||
| } | |||
| } | |||
| }; | |||
| @@ -383,32 +383,34 @@ void MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) | |||
| { | |||
| const MidiMessage& mm = ms.getEventPointer(i)->message; | |||
| const int tick = roundToInt (mm.getTimeStamp()); | |||
| const int delta = jmax (0, tick - lastTick); | |||
| MidiFileHelpers::writeVariableLengthInt (out, delta); | |||
| lastTick = tick; | |||
| if (! mm.isEndOfTrackMetaEvent()) | |||
| { | |||
| const int tick = roundToInt (mm.getTimeStamp()); | |||
| const int delta = jmax (0, tick - lastTick); | |||
| MidiFileHelpers::writeVariableLengthInt (out, delta); | |||
| lastTick = tick; | |||
| const uint8* data = mm.getRawData(); | |||
| int dataSize = mm.getRawDataSize(); | |||
| const uint8* data = mm.getRawData(); | |||
| int dataSize = mm.getRawDataSize(); | |||
| const uint8 statusByte = data[0]; | |||
| const uint8 statusByte = data[0]; | |||
| if (statusByte == lastStatusByte | |||
| && (statusByte & 0xf0) != 0xf0 | |||
| && dataSize > 1 | |||
| && i > 0) | |||
| { | |||
| ++data; | |||
| --dataSize; | |||
| } | |||
| if (statusByte == lastStatusByte | |||
| && (statusByte & 0xf0) != 0xf0 | |||
| && dataSize > 1 | |||
| && i > 0) | |||
| { | |||
| ++data; | |||
| --dataSize; | |||
| } | |||
| out.write (data, dataSize); | |||
| lastStatusByte = statusByte; | |||
| out.write (data, dataSize); | |||
| lastStatusByte = statusByte; | |||
| } | |||
| } | |||
| out.writeByte (0); | |||
| { | |||
| out.writeByte (0); // (tick delta) | |||
| const MidiMessage m (MidiMessage::endOfTrack()); | |||
| out.write (m.getRawData(), m.getRawDataSize()); | |||
| } | |||
| @@ -25,7 +25,7 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| //============================================================================== | |||
| DirectoryIterator::DirectoryIterator (const File& directory, | |||
| bool isRecursive_, | |||
| const String& wildCard_, | |||
| @@ -74,13 +74,13 @@ bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResul | |||
| if (! filename.containsOnly (".")) | |||
| { | |||
| const File fileFound (path + filename, 0); | |||
| bool matches = false; | |||
| if (isDirectory) | |||
| { | |||
| if (isRecursive && ((whatToLookFor & File::ignoreHiddenFiles) == 0 || ! isHidden)) | |||
| subIterator = new DirectoryIterator (fileFound, true, wildCard, whatToLookFor); | |||
| subIterator = new DirectoryIterator (File::createFileWithoutCheckingPath (path + filename), | |||
| true, wildCard, whatToLookFor); | |||
| matches = (whatToLookFor & File::findDirectories) != 0; | |||
| } | |||
| @@ -98,7 +98,7 @@ bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResul | |||
| if (matches) | |||
| { | |||
| currentFile = fileFound; | |||
| currentFile = File::createFileWithoutCheckingPath (path + filename); | |||
| if (isHiddenResult != nullptr) *isHiddenResult = isHidden; | |||
| if (isDirResult != nullptr) *isDirResult = isDirectory; | |||
| @@ -35,14 +35,11 @@ File::File (const String& fullPathName) | |||
| { | |||
| } | |||
| File::File (const String& path, int) | |||
| : fullPath (path) | |||
| { | |||
| } | |||
| File File::createFileWithoutCheckingPath (const String& path) | |||
| { | |||
| return File (path, 0); | |||
| File f; | |||
| f.fullPath = path; | |||
| return f; | |||
| } | |||
| File::File (const File& other) | |||
| @@ -312,7 +309,9 @@ String File::getPathUpToLastSlash() const | |||
| File File::getParentDirectory() const | |||
| { | |||
| return File (getPathUpToLastSlash(), (int) 0); | |||
| File f; | |||
| f.fullPath = getPathUpToLastSlash(); | |||
| return f; | |||
| } | |||
| //============================================================================== | |||
| @@ -948,20 +948,16 @@ private: | |||
| //============================================================================== | |||
| String fullPath; | |||
| // internal way of contructing a file without checking the path | |||
| friend class DirectoryIterator; | |||
| File (const String&, int); | |||
| static String parseAbsolutePath (const String&); | |||
| String getPathUpToLastSlash() const; | |||
| Result createDirectoryInternal (const String& fileName) const; | |||
| bool copyInternal (const File& dest) const; | |||
| bool moveInternal (const File& dest) const; | |||
| Result createDirectoryInternal (const String&) const; | |||
| bool copyInternal (const File&) const; | |||
| bool moveInternal (const File&) const; | |||
| bool setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 creationTime) const; | |||
| void getFileTimesInternal (int64& modificationTime, int64& accessTime, int64& creationTime) const; | |||
| bool setFileReadOnlyInternal (bool shouldBeReadOnly) const; | |||
| static String parseAbsolutePath (const String& path); | |||
| JUCE_LEAK_DETECTOR (File); | |||
| }; | |||
| @@ -295,4 +295,32 @@ void OpenGLFrameBuffer::clear (const Colour& colour) | |||
| } | |||
| } | |||
| void OpenGLFrameBuffer::draw2D (float x1, float y1, | |||
| float x2, float y2, | |||
| float x3, float y3, | |||
| float x4, float y4, | |||
| const Colour& colour) const | |||
| { | |||
| if (pimpl != nullptr) | |||
| { | |||
| glBindTexture (GL_TEXTURE_2D, pimpl->textureID); | |||
| OpenGLHelpers::drawQuad2D (x1, y1, x2, y2, x3, y3, x4, y4, colour); | |||
| glBindTexture (GL_TEXTURE_2D, 0); | |||
| } | |||
| } | |||
| void OpenGLFrameBuffer::draw3D (float x1, float y1, float z1, | |||
| float x2, float y2, float z2, | |||
| float x3, float y3, float z3, | |||
| float x4, float y4, float z4, | |||
| const Colour& colour) const | |||
| { | |||
| if (pimpl != nullptr) | |||
| { | |||
| glBindTexture (GL_TEXTURE_2D, pimpl->textureID); | |||
| OpenGLHelpers::drawQuad3D (x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, colour); | |||
| glBindTexture (GL_TEXTURE_2D, 0); | |||
| } | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -71,8 +71,23 @@ public: | |||
| /** Deselects this buffer as the current OpenGL rendering target. */ | |||
| void releaseCurrentTarget(); | |||
| /** Clears the framebuffer with the specified colour. */ | |||
| void clear (const Colour& colour); | |||
| /** Draws this framebuffer onto the current context, with the specified corner positions. */ | |||
| void draw2D (float x1, float y1, | |||
| float x2, float y2, | |||
| float x3, float y3, | |||
| float x4, float y4, | |||
| const Colour& colour) const; | |||
| /** Draws this framebuffer onto the current context, with the specified corner positions. */ | |||
| void draw3D (float x1, float y1, float z1, | |||
| float x2, float y2, float z2, | |||
| float x3, float y3, float z3, | |||
| float x4, float y4, float z4, | |||
| const Colour& colour) const; | |||
| private: | |||
| class Pimpl; | |||
| friend class ScopedPointer<Pimpl>; | |||
| @@ -38,6 +38,12 @@ void OpenGLHelpers::clear (const Colour& colour) | |||
| glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
| } | |||
| void OpenGLHelpers::setColour (const Colour& colour) | |||
| { | |||
| glColor4f (colour.getFloatRed(), colour.getFloatGreen(), | |||
| colour.getFloatBlue(), colour.getFloatAlpha()); | |||
| } | |||
| void OpenGLHelpers::prepareFor2D (int width, int height) | |||
| { | |||
| glMatrixMode (GL_PROJECTION); | |||
| @@ -46,7 +52,7 @@ void OpenGLHelpers::prepareFor2D (int width, int height) | |||
| #if JUCE_OPENGL_ES | |||
| glOrthof (0.0f, (float) width, 0.0f, (float) height, 0.0f, 1.0f); | |||
| #else | |||
| glOrtho (0.0, width, 0.0, height, 0, 1); | |||
| glOrtho (0.0, width, 0.0, height, 0, 1); | |||
| #endif | |||
| glViewport (0, 0, width, height); | |||
| @@ -54,12 +60,17 @@ void OpenGLHelpers::prepareFor2D (int width, int height) | |||
| void OpenGLHelpers::setPerspective (double fovy, double aspect, double zNear, double zFar) | |||
| { | |||
| const double ymax = zNear * tan (fovy * double_Pi / 360.0); | |||
| const double ymin = -ymax; | |||
| glLoadIdentity(); | |||
| #if JUCE_OPENGL_ES | |||
| glFrustumf (ymin * aspect, ymax * aspect, ymin, ymax, zNear, zFar); | |||
| const float ymax = (float) (zNear * tan (fovy * double_Pi / 360.0)); | |||
| const float ymin = -ymax; | |||
| glFrustumf (ymin * (float) aspect, ymax * (float) aspect, ymin, ymax, (float) zNear, (float) zFar); | |||
| #else | |||
| const double ymax = zNear * tan (fovy * double_Pi / 360.0); | |||
| const double ymin = -ymax; | |||
| glFrustum (ymin * aspect, ymax * aspect, ymin, ymax, zNear, zFar); | |||
| #endif | |||
| } | |||
| @@ -70,13 +81,11 @@ void OpenGLHelpers::drawQuad2D (float x1, float y1, | |||
| float x4, float y4, | |||
| const Colour& colour) | |||
| { | |||
| glColor4f (colour.getFloatRed(), colour.getFloatGreen(), | |||
| colour.getFloatBlue(), colour.getFloatAlpha()); | |||
| #if JUCE_OPENGL_ES | |||
| const GLfloat vertices[] = { x1, y1, x2, y2, x4, y4, x3, y3 }; | |||
| const GLfloat textureCoords[] = { 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f }; | |||
| setColour (colour); | |||
| glEnableClientState (GL_VERTEX_ARRAY); | |||
| glVertexPointer (2, GL_FLOAT, 0, vertices); | |||
| @@ -87,15 +96,6 @@ void OpenGLHelpers::drawQuad2D (float x1, float y1, | |||
| glDisableClientState (GL_NORMAL_ARRAY); | |||
| glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); | |||
| #else | |||
| glBegin (GL_QUADS); | |||
| glTexCoord2i (0, 0); glVertex2f (x1, y1); | |||
| glTexCoord2i (1, 0); glVertex2f (x2, y2); | |||
| glTexCoord2i (1, 1); glVertex2f (x3, y3); | |||
| glTexCoord2i (0, 1); glVertex2f (x4, y4); | |||
| glEnd(); | |||
| #endif | |||
| } | |||
| void OpenGLHelpers::drawQuad3D (float x1, float y1, float z1, | |||
| @@ -104,13 +104,11 @@ void OpenGLHelpers::drawQuad3D (float x1, float y1, float z1, | |||
| float x4, float y4, float z4, | |||
| const Colour& colour) | |||
| { | |||
| glColor4f (colour.getFloatRed(), colour.getFloatGreen(), | |||
| colour.getFloatBlue(), colour.getFloatAlpha()); | |||
| #if JUCE_OPENGL_ES | |||
| const GLfloat vertices[] = { x1, y1, z1, x2, y2, z2, x4, y4, z4, x3, y3, z3 }; | |||
| const GLfloat textureCoords[] = { 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f }; | |||
| setColour (colour); | |||
| glEnableClientState (GL_VERTEX_ARRAY); | |||
| glVertexPointer (3, GL_FLOAT, 0, vertices); | |||
| @@ -121,15 +119,6 @@ void OpenGLHelpers::drawQuad3D (float x1, float y1, float z1, | |||
| glDisableClientState (GL_NORMAL_ARRAY); | |||
| glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); | |||
| #else | |||
| glBegin (GL_QUADS); | |||
| glTexCoord2i (0, 0); glVertex3f (x1, y1, z1); | |||
| glTexCoord2i (1, 0); glVertex3f (x2, y2, z2); | |||
| glTexCoord2i (1, 1); glVertex3f (x3, y3, z3); | |||
| glTexCoord2i (0, 1); glVertex3f (x4, y4, z4); | |||
| glEnd(); | |||
| #endif | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -38,6 +38,9 @@ public: | |||
| /** Clears the current context using the given colour. */ | |||
| static void clear (const Colour& colour); | |||
| /** Sets the current colour using a JUCE colour. */ | |||
| static void setColour (const Colour& colour); | |||
| /** Gives the current context an orthoganal rendering mode for 2D drawing into the given size. */ | |||
| static void prepareFor2D (int width, int height); | |||