mirror of
https://github.com/YACReader/yacreader
synced 2026-03-01 10:22:58 -05:00
338 lines
9.3 KiB
C++
338 lines
9.3 KiB
C++
// Qt RHI-based Coverflow for YACReader
|
|
// Compatible with Qt 6.7+ using QRhiWidget
|
|
#ifndef __YACREADER_FLOW_RHI_H
|
|
#define __YACREADER_FLOW_RHI_H
|
|
|
|
#include <QtGlobal>
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
|
|
|
#include <QRhiWidget>
|
|
#include <QtWidgets>
|
|
#include <QtGui>
|
|
#include <rhi/qrhi.h>
|
|
|
|
#include "pictureflow.h"
|
|
#include "scroll_management.h"
|
|
|
|
// Reuse enums and structs from OpenGL version
|
|
enum Performance {
|
|
low = 0,
|
|
medium,
|
|
high,
|
|
ultraHigh
|
|
};
|
|
|
|
// Cover Vector
|
|
struct YACReader3DVector {
|
|
float x;
|
|
float y;
|
|
float z;
|
|
float rot;
|
|
};
|
|
|
|
// the image/texture info struct
|
|
struct YACReader3DImageRHI {
|
|
QRhiTexture *texture;
|
|
|
|
float width;
|
|
float height;
|
|
|
|
int index;
|
|
|
|
YACReader3DVector current;
|
|
YACReader3DVector animEnd;
|
|
};
|
|
|
|
struct Preset {
|
|
/*** Animation Settings ***/
|
|
float animationStep;
|
|
float animationSpeedUp;
|
|
float animationStepMax;
|
|
float animationFadeOutDist;
|
|
float preRotation;
|
|
float viewRotateLightStrenght;
|
|
float viewRotateAdd;
|
|
float viewRotateSub;
|
|
float viewAngle;
|
|
|
|
/*** Position Configuration ***/
|
|
float cfX;
|
|
float cfY;
|
|
float cfZ;
|
|
float cfRX;
|
|
float cfRY;
|
|
float cfRZ;
|
|
float rotation;
|
|
float xDistance;
|
|
float centerDistance;
|
|
float zDistance;
|
|
float yDistance;
|
|
|
|
float zoom;
|
|
};
|
|
|
|
extern struct Preset defaultYACReaderFlowConfig;
|
|
extern struct Preset presetYACReaderFlowClassicConfig;
|
|
extern struct Preset presetYACReaderFlowStripeConfig;
|
|
extern struct Preset presetYACReaderFlowOverlappedStripeConfig;
|
|
extern struct Preset pressetYACReaderFlowUpConfig;
|
|
extern struct Preset pressetYACReaderFlowDownConfig;
|
|
|
|
class QLabel;
|
|
class ImageLoader3D;
|
|
class ImageLoaderByteArray3D;
|
|
class YACReaderComicFlow3D;
|
|
class YACReaderPageFlow3D;
|
|
|
|
class YACReaderFlow3D : public QRhiWidget, public ScrollManagement
|
|
{
|
|
Q_OBJECT
|
|
|
|
protected:
|
|
int timerId;
|
|
|
|
YACReader3DImageRHI dummy;
|
|
int viewRotateActive;
|
|
float stepBackup;
|
|
|
|
void calcPos(YACReader3DImageRHI &image, int pos);
|
|
void calcVector(YACReader3DVector &vector, int pos);
|
|
bool animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector);
|
|
void prepareInstanceData(const YACReader3DImageRHI &image, bool isReflection, QVector<float> &data);
|
|
|
|
int updateCount;
|
|
int fontSize;
|
|
|
|
// Cached state for the index label to avoid unnecessary updates
|
|
struct IndexLabelState {
|
|
int current = -1;
|
|
int total = -1;
|
|
};
|
|
|
|
// Uniform buffer data structure (must match shader layout)
|
|
struct UniformData {
|
|
float viewProjectionMatrix[16]; // column-major 4x4
|
|
float backgroundColor[3];
|
|
float _pad0; // pad to vec4
|
|
float reflectionUp;
|
|
float reflectionDown;
|
|
float isReflection;
|
|
float _pad1;
|
|
};
|
|
|
|
// Pending texture uploads (for async image loading)
|
|
struct PendingTextureUpload {
|
|
int index;
|
|
QImage image;
|
|
float x;
|
|
float y;
|
|
};
|
|
|
|
// Scene struct encapsulating all RHI resources
|
|
struct Scene {
|
|
// Textures
|
|
std::unique_ptr<QRhiTexture> defaultTexture;
|
|
std::unique_ptr<QRhiTexture> markTexture;
|
|
std::unique_ptr<QRhiTexture> readingTexture;
|
|
|
|
// Buffers
|
|
std::unique_ptr<QRhiBuffer> vertexBuffer;
|
|
std::unique_ptr<QRhiBuffer> instanceBuffer;
|
|
std::unique_ptr<QRhiBuffer> uniformBuffer;
|
|
|
|
// Pipeline and bindings
|
|
std::unique_ptr<QRhiSampler> sampler;
|
|
std::unique_ptr<QRhiGraphicsPipeline> pipeline;
|
|
std::unique_ptr<QRhiShaderResourceBindings> shaderBindings;
|
|
|
|
// Cache of shader resource bindings per texture (raw pointers, owned by this struct)
|
|
QMap<QRhiTexture *, QRhiShaderResourceBindings *> shaderBindingsCache;
|
|
|
|
// Uniform buffer sizing
|
|
int alignedUniformSize = 0;
|
|
int uniformBufferCapacity = 0;
|
|
|
|
// Pending resource updates (accumulated between frames)
|
|
QRhiResourceUpdateBatch *resourceUpdates = nullptr;
|
|
|
|
// Reset all resources (cleans up cache manually)
|
|
void reset()
|
|
{
|
|
qDeleteAll(shaderBindingsCache);
|
|
shaderBindingsCache.clear();
|
|
defaultTexture.reset();
|
|
markTexture.reset();
|
|
readingTexture.reset();
|
|
vertexBuffer.reset();
|
|
instanceBuffer.reset();
|
|
uniformBuffer.reset();
|
|
sampler.reset();
|
|
pipeline.reset();
|
|
shaderBindings.reset();
|
|
alignedUniformSize = 0;
|
|
uniformBufferCapacity = 0;
|
|
resourceUpdates = nullptr;
|
|
}
|
|
};
|
|
|
|
Scene scene;
|
|
QVector<PendingTextureUpload> pendingTextureUploads;
|
|
|
|
// Index label (shows "current/total" in top-left corner)
|
|
QLabel *indexLabel = nullptr;
|
|
IndexLabelState indexLabelState;
|
|
|
|
void timerEvent(QTimerEvent *) override;
|
|
|
|
int numObjects;
|
|
int lazyPopulateObjects;
|
|
bool showMarks;
|
|
QVector<bool> loaded;
|
|
QVector<YACReaderComicReadStatus> marks;
|
|
|
|
QVector<YACReader3DImageRHI> images;
|
|
|
|
bool hasBeenInitialized;
|
|
|
|
Performance performance;
|
|
|
|
/*** Animation Settings ***/
|
|
Preset config;
|
|
|
|
int currentSelected;
|
|
|
|
YACReader3DVector centerPos;
|
|
|
|
/*** Style ***/
|
|
float shadingTop;
|
|
float shadingBottom;
|
|
|
|
float reflectionUp;
|
|
float reflectionBottom;
|
|
|
|
/*** Theme Colors ***/
|
|
QColor backgroundColor;
|
|
QColor textColor;
|
|
|
|
/*** System info ***/
|
|
float viewRotate;
|
|
|
|
static int updateInterval;
|
|
|
|
bool flowRightToLeft;
|
|
|
|
void startAnimationTimer();
|
|
void stopAnimationTimer();
|
|
|
|
// QRhiWidget overrides
|
|
void initialize(QRhiCommandBuffer *cb) override;
|
|
void render(QRhiCommandBuffer *cb) override;
|
|
void releaseResources() override;
|
|
void showEvent(QShowEvent *event) override;
|
|
void resizeEvent(QResizeEvent *event) override;
|
|
|
|
// Index label helpers
|
|
void updateIndexLabel();
|
|
void updateIndexLabelStyle();
|
|
|
|
// Helper methods
|
|
QRhiTexture *createTextureFromImage(QRhiCommandBuffer *cb, const QImage &image);
|
|
void updateUniformBuffer(QRhiCommandBuffer *cb, const UniformData &data);
|
|
void prepareMarkInstanceData(const YACReader3DImageRHI &image, QVector<float> &data);
|
|
void ensureUniformBufferCapacity(int requiredSlots);
|
|
void ensurePipeline();
|
|
void prepareDrawData(const YACReader3DImageRHI &image, bool isReflection, bool isMark,
|
|
const QMatrix4x4 &viewProjectionMatrix, float *outInstanceData,
|
|
UniformData &outUniformData);
|
|
void executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture,
|
|
const float *instanceData, int uniformSlot);
|
|
|
|
protected:
|
|
QRhi *m_rhi = nullptr;
|
|
|
|
public:
|
|
YACReaderFlow3D(QWidget *parent = nullptr, struct Preset p = pressetYACReaderFlowDownConfig);
|
|
virtual ~YACReaderFlow3D();
|
|
|
|
QSize minimumSizeHint() const override;
|
|
|
|
void showPrevious();
|
|
void showNext();
|
|
void setCurrentIndex(int pos);
|
|
void cleanupAnimation();
|
|
void draw();
|
|
void updatePositions();
|
|
void insert(QRhiTexture *texture, float x, float y, int item = -1);
|
|
virtual void remove(int item);
|
|
void add(int item);
|
|
void replace(QRhiTexture *texture, float x, float y, int item);
|
|
void populate(int n);
|
|
YACReader3DImageRHI getCurrentSelected();
|
|
|
|
public slots:
|
|
void setCF_RX(int value);
|
|
void setCF_RY(int value);
|
|
void setCF_RZ(int value);
|
|
void setZoom(int zoom);
|
|
void setRotation(int angle);
|
|
void setX_Distance(int distance);
|
|
void setCenter_Distance(int distance);
|
|
void setZ_Distance(int distance);
|
|
void setCF_Y(int value);
|
|
void setCF_Z(int value);
|
|
void setY_Distance(int value);
|
|
void setFadeOutDist(int value);
|
|
void setLightStrenght(int value);
|
|
void setMaxAngle(int value);
|
|
void setPreset(const Preset &p);
|
|
void setPerformance(Performance performance);
|
|
void useVSync(bool b); // Compatibility method (no-op for RHI)
|
|
void setFlowRightToLeft(bool b);
|
|
|
|
// Theme color setters
|
|
void setBackgroundColor(const QColor &color);
|
|
void setTextColor(const QColor &color);
|
|
|
|
virtual void updateImageData() = 0;
|
|
|
|
void reset();
|
|
void reload();
|
|
|
|
void setShowMarks(bool value);
|
|
void setMarks(QVector<YACReader::YACReaderComicReadStatus> marks);
|
|
void setMarkImage(QImage &image);
|
|
void markSlide(int index, YACReader::YACReaderComicReadStatus status);
|
|
void unmarkSlide(int index);
|
|
void setSlideSize(QSize size);
|
|
void clear();
|
|
void setCenterIndex(unsigned int index);
|
|
void showSlide(int index);
|
|
int centerIndex();
|
|
void updateMarks();
|
|
void render(); // Compatibility method (triggers update())
|
|
void resizeGL(int width, int height); // Compatibility method (no-op for RHI)
|
|
|
|
QVector3D getPlaneIntersection(int x, int y, YACReader3DImageRHI plane);
|
|
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
|
void mousePressEvent(QMouseEvent *event) override;
|
|
void wheelEvent(QWheelEvent *event) override;
|
|
void keyPressEvent(QKeyEvent *event) override;
|
|
|
|
friend class ImageLoader3D;
|
|
friend class ImageLoaderByteArray3D;
|
|
|
|
signals:
|
|
void centerIndexChanged(int);
|
|
void selected(unsigned int);
|
|
};
|
|
|
|
/* Derived flow & loader classes moved to dedicated files:
|
|
- common/rhi/yacreader_comic_flow_rhi.h/.cpp
|
|
- common/rhi/yacreader_page_flow_rhi.h/.cpp
|
|
*/
|
|
|
|
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
|
|
|
#endif // __YACREADER_FLOW_RHI_H
|