mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0025149: Samples - add Qt5/QML sample for Android 4.x
This commit is contained in:
292
samples/qt/AndroidQt/AndroidQt.cxx
Normal file
292
samples/qt/AndroidQt/AndroidQt.cxx
Normal file
@@ -0,0 +1,292 @@
|
||||
// Copyright (c) 2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <AndroidQt_Window.h>
|
||||
#include <AndroidQt.h>
|
||||
#include <AndroidQt_UserInteractionParameters.h>
|
||||
|
||||
#include <AIS_Shape.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <OpenGl_GraphicDriver.hxx>
|
||||
#include <Quantity_Color.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <UnitsAPI.hxx>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <QFileInfo>
|
||||
|
||||
// =======================================================================
|
||||
// function : AndroidQt
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
AndroidQt::AndroidQt()
|
||||
: myFitAllAction (false)
|
||||
{
|
||||
connect (this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*)));
|
||||
|
||||
// set shaders location variable
|
||||
QByteArray aDataRoot = "/data/data/org.qtproject.example.AndroidQt/files/opencascade/shared";
|
||||
qputenv ("CSF_ShadersDirectory", aDataRoot + "/Shaders");
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ReadShapeFromFile
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool AndroidQt::ReadShapeFromFile (QString theFilePath)
|
||||
{
|
||||
QUrl aFileUrl (theFilePath);
|
||||
QString aFilePath = theFilePath;
|
||||
if (aFileUrl.isLocalFile())
|
||||
{
|
||||
aFilePath = QUrl (theFilePath).toLocalFile();
|
||||
}
|
||||
|
||||
if (!QFile (aFilePath).exists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TopoDS_Shape aShape;
|
||||
BRep_Builder aBuildTool;
|
||||
try
|
||||
{
|
||||
OCC_CATCH_SIGNALS
|
||||
|
||||
if (!BRepTools::Read (aShape, aFilePath.toStdString().c_str(), aBuildTool))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!myContext.IsNull())
|
||||
{
|
||||
myContext->EraseAll (Standard_False);
|
||||
|
||||
Handle(AIS_Shape) aShapePrs = new AIS_Shape (aShape);
|
||||
aShapePrs->SetColor (Quantity_Color(1.0, 0.73, 0.2, Quantity_TOC_RGB));
|
||||
|
||||
myContext->Display (aShapePrs, Standard_False);
|
||||
myContext->SetDisplayMode (aShapePrs, AIS_Shaded, Standard_False);
|
||||
}
|
||||
|
||||
myMutex.lock();
|
||||
myFitAllAction = true;
|
||||
myMutex.unlock();
|
||||
|
||||
if (window())
|
||||
{
|
||||
window()->update();
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : InitTouch
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AndroidQt::InitTouch (const double theX,
|
||||
const double theY)
|
||||
{
|
||||
myMutex.lock();
|
||||
myTouchPoint.SetStarts (theX, theY);
|
||||
myMutex.unlock();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : UpdateTouch
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AndroidQt::UpdateTouch (const double theX,
|
||||
const double theY)
|
||||
{
|
||||
myMutex.lock();
|
||||
myTouchPoint.SetEnds (theX, theY);
|
||||
myMutex.unlock();
|
||||
|
||||
if (window())
|
||||
window()->update();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handleWindowChanged
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AndroidQt::handleWindowChanged (QQuickWindow* theWin)
|
||||
{
|
||||
if (theWin == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
connect(theWin, SIGNAL(beforeSynchronizing()), this, SLOT(sync()), Qt::DirectConnection);
|
||||
|
||||
theWin->setClearBeforeRendering (false);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : sync
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AndroidQt::sync()
|
||||
{
|
||||
myViewportSize = window()->size() * window()->devicePixelRatio();
|
||||
|
||||
if (myViewer.IsNull())
|
||||
{
|
||||
initViewer();
|
||||
connect (window(), SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (myViewer->Driver());
|
||||
if (aDriver->getRawGlContext() != eglGetCurrentContext())
|
||||
{
|
||||
initViewer();
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle(AndroidQt_Window) aWindow = Handle(AndroidQt_Window)::DownCast (myView->Window());
|
||||
aWindow->SetSize (myViewportSize.width(), myViewportSize.height());
|
||||
//myView->MustBeResized(); // can be used instead of SetWindow() when EGLsurface has not been changed
|
||||
|
||||
EGLContext anEglContext = eglGetCurrentContext();
|
||||
myView->SetWindow (aWindow, (Aspect_RenderingContext )anEglContext, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : paint
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AndroidQt::paint()
|
||||
{
|
||||
myMutex.lock();
|
||||
|
||||
if (Abs(myTouchPoint.DevX()) + Abs(myTouchPoint.DevY()) > 1)
|
||||
{
|
||||
myView->StartRotation (myTouchPoint.X().first, myTouchPoint.Y().first);
|
||||
myView->Rotation (myTouchPoint.X().second, myTouchPoint.Y().second);
|
||||
|
||||
myTouchPoint.ClearDev();
|
||||
}
|
||||
|
||||
if (myFitAllAction)
|
||||
{
|
||||
myView->FitAll();
|
||||
myFitAllAction = false;
|
||||
}
|
||||
|
||||
myMutex.unlock();
|
||||
|
||||
myView->Redraw();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : initViewer
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool AndroidQt::initViewer()
|
||||
{
|
||||
EGLint aCfgId = 0;
|
||||
int aWidth = 0, aHeight = 0;
|
||||
EGLDisplay anEglDisplay = eglGetCurrentDisplay();
|
||||
EGLContext anEglContext = eglGetCurrentContext();
|
||||
EGLSurface anEglSurf = eglGetCurrentSurface (EGL_DRAW);
|
||||
|
||||
if (anEglDisplay == EGL_NO_DISPLAY
|
||||
|| anEglContext == EGL_NO_CONTEXT
|
||||
|| anEglSurf == EGL_NO_SURFACE)
|
||||
{
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
eglQuerySurface (anEglDisplay, anEglSurf, EGL_WIDTH, &aWidth);
|
||||
eglQuerySurface (anEglDisplay, anEglSurf, EGL_HEIGHT, &aHeight);
|
||||
eglQuerySurface (anEglDisplay, anEglSurf, EGL_CONFIG_ID, &aCfgId);
|
||||
|
||||
const EGLint aConfigAttribs[] = { EGL_CONFIG_ID, aCfgId, EGL_NONE };
|
||||
EGLint aNbConfigs = 0;
|
||||
void* anEglConfig = NULL;
|
||||
|
||||
if (eglChooseConfig (anEglDisplay, aConfigAttribs, &anEglConfig, 1, &aNbConfigs) != EGL_TRUE)
|
||||
{
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!myViewer.IsNull())
|
||||
{
|
||||
Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (myViewer->Driver());
|
||||
Handle(AndroidQt_Window) aWindow = Handle(AndroidQt_Window)::DownCast (myView->Window());
|
||||
if (!aDriver->InitEglContext (anEglDisplay, anEglContext, anEglConfig))
|
||||
{
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
aWindow->SetSize (aWidth, aHeight);
|
||||
myView->SetWindow (aWindow, (Aspect_RenderingContext )anEglContext, NULL, NULL);
|
||||
}
|
||||
|
||||
Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver (NULL, Standard_False);
|
||||
aDriver->ChangeOptions().buffersNoSwap = Standard_True;
|
||||
//aDriver->ChangeOptions().glslWarnings = Standard_True; // for GLSL shaders debug
|
||||
|
||||
if (!aDriver->InitEglContext (anEglDisplay, anEglContext, anEglConfig))
|
||||
{
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
// create viewer
|
||||
myViewer = new V3d_Viewer (aDriver, TCollection_ExtendedString("Viewer").ToExtString(), "", 1000.0,
|
||||
V3d_XposYnegZpos, AndroidQt_UserInteractionParameters::BgColor.Name(), V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT,
|
||||
Standard_True, Standard_False);
|
||||
myViewer->SetDefaultLights();
|
||||
myViewer->SetLightOn();
|
||||
|
||||
// create AIS context
|
||||
myContext = new AIS_InteractiveContext (myViewer);
|
||||
myContext->SetDisplayMode (AIS_Shaded);
|
||||
|
||||
Handle(AndroidQt_Window) aWindow = new AndroidQt_Window (aWidth, aHeight);
|
||||
myView = myViewer->CreateView();
|
||||
|
||||
myView->SetWindow (aWindow, (Aspect_RenderingContext )anEglContext, NULL, NULL);
|
||||
myView->TriedronDisplay (Aspect_TOTP_RIGHT_LOWER, Quantity_NOC_WHITE, 0.08, V3d_ZBUFFER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : release
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AndroidQt::release()
|
||||
{
|
||||
myContext.Nullify();
|
||||
myView.Nullify();
|
||||
myViewer.Nullify();
|
||||
}
|
Reference in New Issue
Block a user