diff --git a/extras/JuceDemo/Source/demos/OpenGLDemo.cpp b/extras/JuceDemo/Source/demos/OpenGLDemo.cpp index 0d8283e30a..fd2e2f46c5 100644 --- a/extras/JuceDemo/Source/demos/OpenGLDemo.cpp +++ b/extras/JuceDemo/Source/demos/OpenGLDemo.cpp @@ -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 (texture1.getSharedImage())->frameBuffer; + OpenGLFrameBuffer& frameBuffer2 = dynamic_cast (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 (r.nextInt (w), r.nextInt (h)), r.nextInt (8) + 3, 10, 20, 0); + g.setColour (Colours::pink.withAlpha (0.4f)); + g.fillPath (pp); + } + } }; diff --git a/modules/juce_audio_basics/midi/juce_MidiFile.cpp b/modules/juce_audio_basics/midi/juce_MidiFile.cpp index 8b51c9e947..76f8301de4 100644 --- a/modules/juce_audio_basics/midi/juce_MidiFile.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiFile.cpp @@ -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()); } diff --git a/modules/juce_core/files/juce_DirectoryIterator.cpp b/modules/juce_core/files/juce_DirectoryIterator.cpp index 6e9201ac3b..cc34d4a2f7 100644 --- a/modules/juce_core/files/juce_DirectoryIterator.cpp +++ b/modules/juce_core/files/juce_DirectoryIterator.cpp @@ -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; diff --git a/modules/juce_core/files/juce_File.cpp b/modules/juce_core/files/juce_File.cpp index 416223ed58..2202344a9c 100644 --- a/modules/juce_core/files/juce_File.cpp +++ b/modules/juce_core/files/juce_File.cpp @@ -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; } //============================================================================== diff --git a/modules/juce_core/files/juce_File.h b/modules/juce_core/files/juce_File.h index 0ca578ba73..2e10bc6703 100644 --- a/modules/juce_core/files/juce_File.h +++ b/modules/juce_core/files/juce_File.h @@ -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); }; diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp index f7941b86bc..57f029b716 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp @@ -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 diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h index 71b270638b..c0ba76652e 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.h @@ -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; diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp index 9b169e9754..19197630f4 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.cpp @@ -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 diff --git a/modules/juce_opengl/opengl/juce_OpenGLHelpers.h b/modules/juce_opengl/opengl/juce_OpenGLHelpers.h index 4b5ba70d50..be781c6d8d 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLHelpers.h +++ b/modules/juce_opengl/opengl/juce_OpenGLHelpers.h @@ -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);