亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

QOpenGLWidget大圖查看器:紋理上傳、MVP矩陣與光標(biāo)縮放

QOpenGLWidget大圖查看器:紋理上傳、MVP矩陣與光標(biāo)縮放 簡(jiǎn)介這份Qt示例工程面向具備一定C基礎(chǔ)、正在學(xué)習(xí)Qt與OpenGL圖形顯示的開發(fā)者聚焦QImage圖片在QOpenGLWidget中的紋理上傳與交互變換問(wèn)題。壓縮包為rar格式共10個(gè)文件、約347KB以3個(gè)cpp和2個(gè)h源碼為核心配合ui界面、qrc資源、pro工程配置及jpg示例圖組成可直接參考的完整工程結(jié)構(gòu)。已有783人學(xué)習(xí)說(shuō)明其在圖像顯示類練習(xí)中具有一定參考價(jià)值。工程內(nèi)容覆蓋initializeGL與paintGL的初始化與繪制流程、紋理過(guò)濾和邊角模式設(shè)置以及通過(guò)模型視圖矩陣實(shí)現(xiàn)縮放、旋轉(zhuǎn)和平移的思路同時(shí)結(jié)合鼠標(biāo)、鍵盤輸入更新變換參數(shù)并控制重繪以保持交互流暢。讀者可據(jù)此理解QImage轉(zhuǎn)紋理、視口適配和交互變換的組織方式作為圖像查看器或圖形界面二次開發(fā)的起點(diǎn)。1. QOpenGLWidget 貼圖這件事從 QLabel 換到 GL 畫布的那一步拿 QLabel 顯示圖片一開始都很順直到你放進(jìn)去一張 8000×6000 的掃描件。滾輪一放大QPixmap 要重新做一次 CPU 插值幾十毫秒就過(guò)去了按住鼠標(biāo)拖動(dòng)主線程直接被堵住畫面一卡一頓松手才啪地跳到最終位置。做圖像標(biāo)注、圖紙預(yù)覽、看圖工具這類要長(zhǎng)時(shí)間盯細(xì)節(jié)的軟件這個(gè)體驗(yàn)基本沒法交付。換成 QOpenGLWidget 的思路其實(shí)很樸素讓 QImage 只走一次內(nèi)存到顯存的拷貝變成一張紋理之后所有縮放、旋轉(zhuǎn)、平移都只是改一個(gè) 4×4 矩陣?yán)锏膸讉€(gè)數(shù)重繪交給 GPU大圖縮放穩(wěn)定在一幀一次 draw call。這份源碼素材-template 拆的就是這個(gè)最小閉環(huán)四類操作背后只有一條數(shù)據(jù)鏈路和一組矩陣把這條鏈走通再加任何功能都是往上疊。適合剛接觸 Qt 與 OpenGL 的同學(xué)照著跑通也適合手上正有一個(gè) QLabel 看圖控件準(zhǔn)備換掉的開發(fā)者。2. 工程骨架與數(shù)據(jù)鏈路一張 QImage 走到屏幕要過(guò)哪幾道關(guān)2.1 四個(gè)環(huán)節(jié)解碼、上傳、變換、繪制整條鏈路拆開只有四步邊界清楚到可以用一句話描述QImage 在 CPU 側(cè)被規(guī)范化成 RGBA8888 并垂直翻轉(zhuǎn)通過(guò) glTexImage2D 上傳成 2D 紋理繪制時(shí)用一個(gè)正交投影矩陣把像素坐標(biāo)系映射到 NDC再把平移、旋轉(zhuǎn)、縮放疊成一個(gè)模型矩陣最后畫一個(gè)和圖片等尺寸的四邊形采樣紋理輸出。四個(gè)環(huán)節(jié)各自有獨(dú)立的失敗點(diǎn)這是排查時(shí)最省時(shí)間的一張地圖環(huán)節(jié)關(guān)鍵函數(shù)典型失敗表現(xiàn)解碼QImage::load / convertToFormat通道錯(cuò)位、透明區(qū)變黑上傳glGenTextures / glTexImage2D黑屏、斜條紋、越界讀變換QMatrix4x4 組裝縮放跑偏、旋轉(zhuǎn)不繞中心繪制glDrawArrays shader有頂點(diǎn)無(wú)像素、上下顛倒很多人第一次寫會(huì)把這四步揉在 paintGL 里結(jié)果一改縮放就得重新傳紋理幀率立刻掉到個(gè)位數(shù)。正確的切法是上傳只在換圖時(shí)發(fā)生一次paintGL 里只做變換和采樣。2.2 類結(jié)構(gòu)與目錄組織工程不需要很復(fù)雜一個(gè)畫布類吃下所有 GL 相關(guān)代碼主窗口只管 UI 和文件對(duì)話框這樣二次開發(fā)時(shí)改動(dòng)面可控。目錄大致長(zhǎng)這樣ImageViewerGL/ ├── CMakeLists.txt ├── main.cpp ├── widgets/ │ ├── ImageCanvasWidget.h # 畫布本體GL 代碼全在這里 │ ├── ImageCanvasWidget.cpp │ ├── ImageViewerWindow.h # 主窗口打開、復(fù)位、關(guān)于 │ └── ImageViewerWindow.cpp ├── shaders/ │ ├── image.vert │ └── image.frag └── resources.qrc # 把 shader 打成資源省掉運(yùn)行時(shí)路徑問(wèn)題Qt6 里 QOpenGLWidget 已經(jīng)從 Widgets 拆到了獨(dú)立模塊CMake 配置少寫一行就是鏈接報(bào)錯(cuò)find_package(Qt6 REQUIRED COMPONENTS Widgets OpenGLWidgets) add_executable(ImageViewerGL main.cpp widgets/ImageCanvasWidget.cpp widgets/ImageViewerWindow.cpp ) # 注意 OpenGLWidgets 是獨(dú)立組件只鏈 Widgets 會(huì)在 QOpenGLWidget 構(gòu)造函數(shù)上炸 target_link_libraries(ImageViewerGL PRIVATE Qt6::Widgets Qt6::OpenGLWidgets) set_target_properties(ImageViewerGL PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE )提示Qt5 用QT opengl就夠了Qt6 必須顯式找 OpenGLWidgets兩套 CMake 寫法不通用從舊工程遷移時(shí)優(yōu)先查這一行。畫布類的公開接口刻意收得很窄外層只認(rèn)識(shí)三個(gè)方法加載圖片、復(fù)位視圖、設(shè)置背景色。內(nèi)部狀態(tài)全部私有這樣后面加標(biāo)注層、加 ROI 框選時(shí)外部邏輯不需要知道矩陣怎么算。2.3 初始化順序initializeGL 里到底該放什么QOpenGLWidget 的三個(gè)虛函數(shù)有嚴(yán)格調(diào)用時(shí)機(jī)initializeGL只在上下文第一次成功建立后調(diào)一次resizeGL在尺寸變化時(shí)調(diào)paintGL每幀調(diào)。順序錯(cuò)了就是典型黑屏——在initializeGL之前調(diào)任何gl開頭的函數(shù)要么空指針要么靜默失敗。class ImageCanvasWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: explicit ImageCanvasWidget(QWidget *parent nullptr); ~ImageCanvasWidget() override; bool loadImage(const QString filePath); // 唯一換圖入口 void resetView(); // 復(fù)位縮放 1.0、旋轉(zhuǎn) 0、居中 void rotateBy(float degrees); // 相對(duì)旋轉(zhuǎn)供工具欄和快捷鍵調(diào) protected: void initializeGL() override; void resizeGL(int w, int h) override; void paintGL() override; void wheelEvent(QWheelEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; private: void uploadTexture(const QImage img); // QImage - GL 紋理只在換圖時(shí)調(diào) void rebuildQuad(); // 按圖片尺寸重建頂點(diǎn)緩沖 QMatrix4x4 buildMvp() const; // 投影 * 模型逐幀組裝 GLuint m_texture 0; QOpenGLShaderProgram m_program; QOpenGLBuffer m_vbo{QOpenGLBuffer::VertexBuffer}; QOpenGLVertexArrayObject m_vao; QImage m_image; // 保留原圖導(dǎo)出/重傳都靠它 QSize m_texSize; // 原圖尺寸算初始縮放用 float m_scale 1.0f; // 縮放系數(shù)1.0 表示 1 像素對(duì) 1 像素 float m_rotation 0.0f; // 旋轉(zhuǎn)角度單位度逆時(shí)針為正 QVector2D m_translation{0.0f, 0.0f}; // 平移量單位屏幕像素 QPointF m_lastPos; // 上一幀鼠標(biāo)位置拖拽用 bool m_dragging false; };繼承QOpenGLFunctions是為了拿到跨平臺(tái)的 GL 函數(shù)指針集合——Qt 幫你做了QOpenGLContext::getProcAddress那一套你不必再引 GLEW 或 glad這在只有 Widgets 依賴的項(xiàng)目里很省事。代價(jià)是只能用 OpenGL ES 2.0 / 2.1 這個(gè)基線如果你要用 compute shader 或幾何著色器就得換成QOpenGLExtraFunctions或者自己加載。initializeGL里的順序不能亂void ImageCanvasWidget::initializeGL() { // 1. Qt6 必須顯式初始化函數(shù)解析表少了這行后面所有 gl* 都是空指針 initializeOpenGLFunctions(); // 2. shader 編譯鏈接失敗必須立刻暴露不要靜默跳過(guò) if (!m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, kVertexShader) || !m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, kFragmentShader) || !m_program.link()) { qWarning(shader 編譯失敗: %s, qPrintable(m_program.log())); return; } // 3. VAO/VBO 只創(chuàng)建不填充頂點(diǎn)數(shù)據(jù)要等圖片尺寸確定后才能寫 m_vao.create(); m_vbo.create(); // 4. 固定管線那套混色狀態(tài)深色背景配半透明圖片時(shí)需要 glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }第 4 步的GL_BLEND是給帶 alpha 通道的 PNG 準(zhǔn)備的如果你只顯示不透明圖片這一行可以省。第 2 步的qWarning打印m_program.log()很關(guān)鍵——shader 編譯錯(cuò)誤不會(huì)拋異常只會(huì)在日志里留一行不打印出來(lái)就是純黑屏加一頭霧水。3. 核心渲染鏈路拆解紋理上傳、著色器與 MVP 矩陣3.1 QImage 轉(zhuǎn)紋理格式、對(duì)齊、翻轉(zhuǎn)三件事這是整個(gè)項(xiàng)目里最容易翻車的一段因?yàn)槿齻€(gè)坑全藏在兩行代碼里。QImage 的像素格式五花八門Format_ARGB32、Format_RGB888、Format_Grayscale8……OpenGL 只認(rèn)它自己那一套枚舉中間必須做一次格式收斂。選Format_RGBA8888是因?yàn)樗膬?nèi)存排布是 R、G、B、A 順序和GL_RGBA的期望完全一致不需要再做通道重排。void ImageCanvasWidget::uploadTexture(const QImage img) { // 1. 格式收斂RGBA8888 的內(nèi)存序和 GL_RGBA 嚴(yán)格對(duì)應(yīng)省掉通道交換 QImage normalized img.convertToFormat(QImage::Format_RGBA8888); // 2. 垂直翻轉(zhuǎn)QImage 原點(diǎn)在左上GL 紋理原點(diǎn)在左下這里翻一次 // 著色器里的 uv 就可以老老實(shí)實(shí)寫 (0,0)-(1,1)邏輯只留在一個(gè)地方 normalized normalized.mirrored(false, true); if (m_texture 0) { glGenTextures(1, m_texture); } glBindTexture(GL_TEXTURE_2D, m_texture); // 3. 行對(duì)齊寬度不是 4 的倍數(shù)時(shí)默認(rèn) 4 字節(jié)對(duì)齊會(huì)讀串行畫面呈斜條紋 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, normalized.width(), normalized.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, normalized.constBits()); // 4. 縮小時(shí)用 mipmap 三線性放大時(shí)用線性只用 GL_LINEAR 縮小會(huì)明顯閃爍 glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 5. 邊緣 clamp避免紋理采樣越界時(shí)出現(xiàn)半透明黑邊 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); m_texSize normalized.size(); m_image img; // 存原圖導(dǎo)出時(shí)不要再?gòu)?GPU 讀回來(lái) }參數(shù)逐個(gè)說(shuō)清楚GL_RGBA8是內(nèi)部格式8 位每通道夠用且顯存占用可控如果做醫(yī)療影像要 16 位精度這里換成GL_RGBA16同時(shí) QImage 那邊轉(zhuǎn)Format_RGBA64。glPixelStorei(GL_UNPACK_ALIGNMENT, 1)是必須的。寬度 3 的倍數(shù)、又不是 4 的倍數(shù)的圖比如 RGB888 的 1023 像素寬默認(rèn) 4 字節(jié)對(duì)齊會(huì)讓驅(qū)動(dòng)多讀幾個(gè)字節(jié)畫面直接變成斜著的色帶。這個(gè)現(xiàn)象非常迷惑因?yàn)閳D不大就完全正常圖一大就錯(cuò)。mirrored(false, true)和第二參數(shù)true是垂直鏡像。如果你不想在 CPU 側(cè)翻也可以在頂點(diǎn)數(shù)據(jù)里把 v 坐標(biāo)寫成1.0 - v但兩邊千萬(wàn)別都做否則畫面上下顛倒回來(lái)又顛倒回去最后看起來(lái)正常一換圖就露餡。紋理尺寸還有硬限制GL_MAX_TEXTURE_SIZE在老舊集顯上可能只有 8192 或 4096。超過(guò)這個(gè)尺寸glTexImage2D直接報(bào)GL_INVALID_VALUE畫面全黑。工業(yè)相機(jī)、衛(wèi)星圖、切片掃描這類動(dòng)輒兩萬(wàn)像素的材料很正常比較穩(wěn)妥的做法是分塊tile上傳或者先等比縮到合法尺寸再傳原圖留給導(dǎo)出用。3.2 頂點(diǎn)數(shù)據(jù)與著色器一張四邊形的完整定義幾何部分簡(jiǎn)單到不需要索引緩沖四個(gè)頂點(diǎn)畫一個(gè) triangle strip 就完事。頂點(diǎn)坐標(biāo)直接用圖片像素坐標(biāo)0,0 到 w,h這樣正交投影矩陣寫起來(lái)最直觀鼠標(biāo)坐標(biāo)也能直接參與運(yùn)算不用來(lái)回做歸一化換算。void ImageCanvasWidget::rebuildQuad() { const float w static_castfloat(m_texSize.width()); const float h static_castfloat(m_texSize.height()); // 布局x, y, u, v 交叉排列一次 allocate 搞定位置和紋理坐標(biāo) const GLfloat verts[] { 0.0f, 0.0f, 0.0f, 0.0f, // 左上 w, 0.0f, 1.0f, 0.0f, // 右上 0.0f, h, 0.0f, 1.0f, // 左下 w, h, 1.0f, 1.0f, // 右下 }; m_vao.bind(); m_vbo.bind(); m_vbo.allocate(verts, sizeof(verts)); m_program.bind(); // 參數(shù)含義location0類型 float起始偏移 0每頂點(diǎn) 2 分量跨距 4 個(gè) float m_program.enableAttributeArray(0); m_program.setAttributeBuffer(0, GL_FLOAT, 0, 2, 4 * sizeof(GLfloat)); // location1從第 3 個(gè) float 開始2 分量跨距同上 m_program.enableAttributeArray(1); m_program.setAttributeBuffer(1, GL_FLOAT, 2 * sizeof(GLfloat), 2, 4 * sizeof(GLfloat)); m_program.release(); m_vbo.release(); m_vao.release(); }setAttributeBuffer的最后一個(gè)參數(shù)是 stride這里寫4 * sizeof(GLfloat)表示每隔 16 字節(jié)取下一個(gè)頂點(diǎn)。如果寫成 0讓驅(qū)動(dòng)自己推某些老驅(qū)動(dòng)會(huì)算錯(cuò)顯式寫死更保險(xiǎn)。location0 / 1是靠 shader 里的layout(location ...)硬綁定的兩邊必須對(duì)得上對(duì)不上就是純黑。兩個(gè) shader 保持最小// image.vert #version 330 core layout(location 0) in vec2 aPos; layout(location 1) in vec2 aTexCoord; uniform mat4 uMvp; out vec2 vTexCoord; void main() { vTexCoord aTexCoord; // 注意這里乘的是完整 MVP任何變換都在 CPU 側(cè)算好shader 不做二次加工 gl_Position uMvp * vec4(aPos, 0.0, 1.0); }// image.frag #version 330 core in vec2 vTexCoord; uniform sampler2D uTexture; out vec4 fragColor; void main() { fragColor texture(uTexture, vTexCoord); }片元著色器里不寫任何 if 和分支——GPU 最怕這個(gè)。如果你想加灰度化反色亮度對(duì)比度直接在texture()之后做一個(gè)mix或加減代價(jià)幾乎為零但如果寫if (vTexCoord.x 0.5)性能曲線會(huì)立刻變得難看。3.3 buildMvp平移、旋轉(zhuǎn)、縮放的合成順序矩陣這塊是玄學(xué)重災(zāi)區(qū)。QMatrix4x4 的乘法和數(shù)學(xué)課本一致但代碼里鏈?zhǔn)秸{(diào)用的順序和直覺是反的m.translate(); m.rotate(); m.scale();實(shí)際效果是先縮放、再旋轉(zhuǎn)、最后平移因?yàn)槊看握{(diào)用都在右乘新矩陣。設(shè)計(jì)意圖很明確圖片自己的坐標(biāo)系里先繞圖片中心縮放再繞圖片中心旋轉(zhuǎn)然后整體移動(dòng)到畫布中心并疊加用戶的平移量。所以順序必須是 translate → rotate → scale → 反向平移回原點(diǎn)。QMatrix4x4 ImageCanvasWidget::buildMvp() const { QMatrix4x4 proj; // y 軸向下bottom h, top 0和屏幕坐標(biāo)系一致 // 鼠標(biāo)坐標(biāo)可以直接當(dāng)世界坐標(biāo)用不需要再做 y 翻轉(zhuǎn) proj.ortho(0.0f, static_castfloat(width()), static_castfloat(height()), 0.0f, -1.0f, 1.0f); QMatrix4x4 mv; // 1. 把畫布中心 用戶平移量當(dāng)作圖片中心的落點(diǎn) mv.translate(width() * 0.5f m_translation.x(), height() * 0.5f m_translation.y()); // 2. 繞 Z 軸旋轉(zhuǎn)正數(shù)為逆時(shí)針 mv.rotate(m_rotation, 0.0f, 0.0f, 1.0f); // 3. 等比縮放 mv.scale(m_scale, m_scale); // 4. 把圖片自身中心挪到原點(diǎn) —— 少了這行縮放和旋轉(zhuǎn)會(huì)繞畫布左上角 // 表現(xiàn)就是放大時(shí)圖片往右下角飛出屏幕 mv.translate(-m_texSize.width() * 0.5f, -m_texSize.height() * 0.5f); return proj * mv; }第 4 行的反向平移是整個(gè)矩陣的靈魂。它的物理含義是把圖片坐標(biāo)系的中心挪到原點(diǎn)這樣第 2、3 步的旋轉(zhuǎn)和縮放天然繞中心發(fā)生。很多人圖省事把 scale 寫在 translate 前面代碼看起來(lái)只差一行運(yùn)行起來(lái)圖片就是繞著左上角放大越放越偏還以為是自己縮放算法寫錯(cuò)了。proj * mv的乘法順序也不能改投影矩陣在最左模型矩陣在右。寫成mv * proj的后果是畫面上什么都沒有且沒有任何報(bào)錯(cuò)。3.4 paintGL一幀的完整執(zhí)行順序void ImageCanvasWidget::paintGL() { glClearColor(0.13f, 0.14f, 0.16f, 1.0f); // 深灰底淺色圖邊緣更清楚 glClear(GL_COLOR_BUFFER_BIT); if (m_texture 0 || m_texSize.isEmpty()) { return; // 還沒加載圖片只清屏 } m_program.bind(); m_program.setUniformValue(uMvp, buildMvp()); m_program.setUniformValue(uTexture, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_texture); m_vao.bind(); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_vao.release(); m_program.release(); }逐行解釋關(guān)鍵點(diǎn)setUniformValue(uTexture, 0)里的 0 是紋理單元編號(hào)必須和glActiveTexture(GL_TEXTURE0)對(duì)上對(duì)不上就是采樣到一張空紋理畫面純黑。GL_TRIANGLE_STRIP用 4 個(gè)頂點(diǎn)畫兩個(gè)三角形比GL_TRIANGLES少傳兩個(gè)頂點(diǎn)雖然在這里省不了多少但習(xí)慣值得保留。整個(gè)paintGL里沒有任何glTexImage2D這是幀率能穩(wěn)住的前提。換圖時(shí)才調(diào)uploadTexturerebuildQuad然后update()一次。4. 交互層實(shí)現(xiàn)滾輪縮放、拖拽平移與旋轉(zhuǎn)的坐標(biāo)換算4.1 鼠標(biāo)事件分發(fā)與狀態(tài)管理三個(gè)鼠標(biāo)事件各管一攤互不打擾左鍵按下開始拖拽左鍵移動(dòng)累加平移量滾輪改縮放系數(shù)右鍵拖拽改旋轉(zhuǎn)角。狀態(tài)用一個(gè)m_dragging布爾量 一個(gè)m_lastPos就能覆蓋不需要維護(hù)狀態(tài)機(jī)。void ImageCanvasWidget::mousePressEvent(QMouseEvent *e) { if (e-button() Qt::LeftButton) { m_dragging true; m_lastPos e-position(); // Qt6 用 position()Qt5 是 pos() setCursor(Qt::ClosedHandCursor); } QOpenGLWidget::mousePressEvent(e); } void ImageCanvasWidget::mouseMoveEvent(QMouseEvent *e) { if (!m_dragging || !(e-buttons() Qt::LeftButton)) { return; } const QPointF delta e-position() - m_lastPos; m_lastPos e-position(); // 平移量直接在屏幕像素空間累加和 ortho 的像素單位完全一致 // 中間不需要任何比例換算這也是選像素坐標(biāo)系的最大好處 m_translation QVector2D(static_castfloat(delta.x()), static_castfloat(delta.y())); update(); // 單幀請(qǐng)求重繪不要用 while 或 timer 去刷 } void ImageCanvasWidget::mouseReleaseEvent(QMouseEvent *e) { if (e-button() Qt::LeftButton) { m_dragging false; unsetCursor(); } QOpenGLWidget::mouseReleaseEvent(e); }e-position()返回的是邏輯像素DPI 無(wú)關(guān)而m_translation也是邏輯像素兩邊單位一致。如果你不小心一邊用了devicePixelRatio乘過(guò)的物理像素拖拽速度就會(huì)變成 2 倍或 0.5 倍高 DPI 屏上線普通屏上一切正常——這種問(wèn)題最難查因?yàn)殚_發(fā)機(jī)往往是普通屏。4.2 以光標(biāo)為錨點(diǎn)的縮放最樸素的實(shí)現(xiàn)是滾輪一下m_scale * 1.15圍繞畫布中心放大。用起來(lái)會(huì)讓用戶很煩想看清楚畫面右上角的細(xì)節(jié)滾幾圈之后那塊內(nèi)容已經(jīng)跑到屏幕外面去了得不停拖回來(lái)。好用的看圖工具都做光標(biāo)錨定——放大時(shí)鼠標(biāo)指針下面那個(gè)像素點(diǎn)保持不動(dòng)。推導(dǎo)不復(fù)雜把屏幕坐標(biāo)到世界坐標(biāo)的映射寫成一行screen R · S · (world ? c) center t其中 R 是旋轉(zhuǎn)S 是縮放c 是圖片中心t 是平移量。要求縮放從 S 變到 S 之后同一個(gè) screen 對(duì)應(yīng)的 world 不變解出新的平移量t pivot · (1 ? k) t · k, 其中 k S/Spivot 鼠標(biāo)位置 ? 畫布中心落到代碼里只有六行void ImageCanvasWidget::wheelEvent(QWheelEvent *e) { const float steps e-angleDelta().y() / 120.0f; // 一格滾輪 120 if (qFuzzyIsNull(steps)) { return; } const float oldScale m_scale; // 1.15^steps往上滾放大往下滾縮小指數(shù)形式保證放大縮小完全對(duì)稱 m_scale std::clamp(oldScale * std::pow(1.15f, steps), 0.02f, 64.0f); // 錨定公式k 是新舊縮放比pivot 是鼠標(biāo)相對(duì)畫布中心的偏移 const float k m_scale / oldScale; const QPointF pos e-position(); const QVector2D pivot(static_castfloat(pos.x() - width() * 0.5), static_castfloat(pos.y() - height() * 0.5)); m_translation pivot * (1.0f - k) m_translation * k; update(); e-accept(); }幾個(gè)參數(shù)值得說(shuō)明std::pow(1.15f, steps)里的 1.15 是手感系數(shù)試過(guò) 1.1、1.2、1.31.15 在大圖上大概是滾三格看清楚一小塊的節(jié)奏再大就容易失控。std::clamp的上下限 0.02 和 64 是防呆——低于 0.02 時(shí)一張 10000 像素的圖只剩 200 像素寬用戶會(huì)以為圖沒了高于 64 時(shí)浮點(diǎn)精度開始不夠用邊緣會(huì)出現(xiàn)抖動(dòng)。這兩個(gè)邊界值不是隨便定的是長(zhǎng)時(shí)間試出來(lái)的。還有一點(diǎn)容易忽略公式里的pivot用的是畫布中心而不是圖片中心。這里有個(gè)前提buildMvp里平移量的基準(zhǔn)點(diǎn)也是畫布中心兩邊必須統(tǒng)一。要是某天你把基準(zhǔn)改成圖片中心這個(gè)公式就得跟著重寫。4.3 拖拽旋轉(zhuǎn)與視圖復(fù)位旋轉(zhuǎn)不用太花哨右鍵橫向拖動(dòng)改角度加上一個(gè)鍵盤 R 鍵做 90° 步進(jìn)覆蓋絕大多數(shù)用法。void ImageCanvasWidget::setRotationFromDrag(qreal dx) { // 每拖 2 像素轉(zhuǎn) 1 度符號(hào)取反是因?yàn)槠聊?y 向下、逆時(shí)針為正 m_rotation std::fmod(m_rotation - static_castfloat(dx) * 0.5f, 360.0f); if (m_rotation 0.0f) { m_rotation 360.0f; // 歸一化到 [0, 360)避免數(shù)值越滾越大 } update(); } void ImageCanvasWidget::rotateBy(float degrees) { m_rotation std::fmod(m_rotation degrees, 360.0f); update(); } void ImageCanvasWidget::resetView() { m_scale 1.0f; m_rotation 0.0f; m_translation QVector2D(0.0f, 0.0f); update(); }std::fmod那一步是后悔藥。如果不做歸一化用戶按住右鍵轉(zhuǎn)十圈m_rotation就變成 3600浮點(diǎn)精度一點(diǎn)點(diǎn)累積轉(zhuǎn)回 0 度時(shí)畫面會(huì)有微小傾斜。歸一化之后最多只有 359 的誤差肉眼看不出來(lái)。復(fù)位按鈕也別只復(fù)位縮放——把旋轉(zhuǎn)和平移一起歸零否則用戶點(diǎn)了復(fù)位發(fā)現(xiàn)圖還是歪的體驗(yàn)很怪。5. 避坑與排查黑屏、倒像、斜條紋、泄漏這四類問(wèn)題5.1 環(huán)境與初始化類一進(jìn)來(lái)就是純黑現(xiàn)象程序能起來(lái)窗口也有但畫布區(qū)域一片黑什么都看不到日志里也沒有異常。原因絕大多數(shù)是initializeOpenGLFunctions()沒調(diào)或者 shaderlink()失敗后被靜默跳過(guò)。Qt6 里QOpenGLFunctions的函數(shù)指針要靠這個(gè)調(diào)用填充不調(diào)的話第一次glGenTextures就是空指針在部分平臺(tái)上直接崩在另一些平臺(tái)上靜默返回 0。另一個(gè)高頻原因是鏈接時(shí)只帶了Qt6::Widgets沒帶Qt6::OpenGLWidgets編譯期不報(bào)錯(cuò)運(yùn)行時(shí)構(gòu)造 QOpenGLWidget 才炸。解決把a(bǔ)ddShaderFromSourceCode和link()的返回值全部檢查失敗時(shí)用qWarning打印m_program.log()initializeGL第一行固定寫initializeOpenGLFunctions()。如果還是沒有輸出檢查QSurfaceFormat有沒有在QApplication構(gòu)造之前設(shè)置——setDefaultFormat必須在main里QApplication a(argc, argv);之前調(diào)之后調(diào)無(wú)效這是個(gè)經(jīng)典的時(shí)間窗口問(wèn)題。5.2 畫面表現(xiàn)類圖片上下顛倒或出現(xiàn)斜條紋現(xiàn)象 A圖能顯示但是上下倒著的文字也反了。原因 AQImage 原點(diǎn)在左上、GL 紋理原點(diǎn)在左下兩邊坐標(biāo)系不一致。如果只在uploadTexture里做了mirrored(false, true)卻又在頂點(diǎn)數(shù)據(jù)里把 v 坐標(biāo)寫成1.0 - v等于翻了兩次看起來(lái)又正了一旦換一種加載路徑比如從內(nèi)存 buffer 而不是文件只走其中一處翻轉(zhuǎn)立刻就顛倒。解決 A翻轉(zhuǎn)只做一次且固定在一個(gè)地方。這個(gè)項(xiàng)目的做法是統(tǒng)一在uploadTexture里翻頂點(diǎn) uv 永遠(yuǎn)寫(0,0)-(1,1)誰(shuí)改了翻轉(zhuǎn)邏輯必須同步檢查另一處。現(xiàn)象 B圖片邊緣出現(xiàn)斜著的彩色條紋或者右下角有一片噪點(diǎn)。原因 BglPixelStorei(GL_UNPACK_ALIGNMENT, 1)沒寫驅(qū)動(dòng)按 4 字節(jié)對(duì)齊讀行寬度不是 4 的倍數(shù)的圖必然讀串行。解決 B上傳紋理前固定加一行g(shù)lPixelStorei(GL_UNPACK_ALIGNMENT, 1)。這個(gè)設(shè)置是全局狀態(tài)會(huì)一直保留但建議每次上傳前都設(shè)避免被別處改掉后踩坑。5.3 交互與數(shù)值類放大后圖片往角落跑現(xiàn)象滾輪放大幾次之后圖片不是圍繞光標(biāo)放大而是快速往右下角飛出去最后完全看不見或者拖拽時(shí)手感明顯黏跟手的距離對(duì)不上。原因buildMvp里少寫了最后那句反向平移mv.translate(-w/2, -h/2)縮放和旋轉(zhuǎn)就繞畫布左上角發(fā)生。拖拽黏的原因通常是單位不統(tǒng)一——e-position()返回邏輯像素而平移量如果按物理像素累加高 DPI 屏上速度就變成 2 倍。解決矩陣鏈的尾部必須補(bǔ)上把圖片中心移到原點(diǎn)這一步坐標(biāo)換算全程只用邏輯像素如果確實(shí)需要物理像素統(tǒng)一在resizeGL里乘一次devicePixelRatioF()別散落在各個(gè)事件處理里。檢查方法很簡(jiǎn)單把m_texSize打出來(lái)再打印一次鼠標(biāo)位置經(jīng)過(guò)buildMvp().inverted()映射后的世界坐標(biāo)看看是不是落在[0, w] × [0, h]里。5.4 性能與資源類連續(xù)換圖幾十次后卡死現(xiàn)象反復(fù)打開不同的圖片內(nèi)存占用一路漲最后系統(tǒng)卡頓甚至進(jìn)程被殺或者大圖切換時(shí)有一秒多的白屏。原因glGenTextures每次換圖都新建紋理舊的沒glDeleteTextures顯存泄漏。另一種是每次paintGL都調(diào)glTexImage2D重新上傳一張 8000×6000 的 RGBA 圖每幀要拷 180MB 到顯存幀率自然崩。解決uploadTexture里先判m_texture ! 0就復(fù)用現(xiàn)有紋理 ID只在尺寸變化時(shí)重建paintGL里絕不重新上傳。如果是同一尺寸的圖頻繁刷新比如視頻幀用glTexSubImage2D替換整張glTexImage2D后者要重新分配顯存前者只覆蓋數(shù)據(jù)快一個(gè)數(shù)量級(jí)。析構(gòu)函數(shù)里記得makeCurrent()之后再glDeleteTextures直接刪會(huì)因?yàn)闆]有當(dāng)前上下文而失敗。注意QOpenGLWidget在銷毀時(shí)上下文可能已經(jīng)失效~ImageCanvasWidget里刪紋理必須自己makeCurrent()Qt 不會(huì)幫你。6. 二次開發(fā)從單圖查看器擴(kuò)到多圖層標(biāo)注器的改造思路這個(gè)畫布跑通之后最有價(jià)值的延伸是把它往多圖層方向改。單圖查看器的瓶頸在m_texture只有一個(gè)一旦要做底圖 標(biāo)注層 ROI 框選就得把紋理和矩陣抽成獨(dú)立的圖層結(jié)構(gòu)struct Layer { GLuint texture 0; QSize size; QMatrix4x4 localTransform; // 圖層自身的偏移/縮放相對(duì)畫布為恒等 float opacity 1.0f; bool visible true; }; QVectorLayer m_layers;改造的關(guān)鍵是把buildMvp拆成兩級(jí)投影矩陣proj全局一份每個(gè)圖層自己的模型矩陣單獨(dú)算繪制時(shí)proj * layer.localTransform逐個(gè)上傳。這樣拖拽平移只改全局的視圖矩陣單獨(dú)挪某個(gè)標(biāo)注框只改對(duì)應(yīng)圖層的localTransform互不干擾也不用重新上傳紋理。第二個(gè)常見需求是導(dǎo)出當(dāng)前視圖。不要用QPixmap::grabWidget那截的是窗口會(huì)被遮擋、被 DPI 縮放。正確做法是grabFramebuffer()它直接讀 FBO拿到的是純繪制內(nèi)容bool ImageCanvasWidget::exportView(const QString path) { makeCurrent(); // 讀 FBO 前必須綁定上下文 const QImage frame grabFramebuffer(); doneCurrent(); return frame.save(path); // 格式由后綴決定 }第三個(gè)方向是精度。如果做的是工業(yè)檢測(cè)、遙感、病理切片圖片動(dòng)輒兩萬(wàn)像素以上GL_MAX_TEXTURE_SIZE直接卡死。這時(shí)要么按 2048 或 4096 切塊每塊一張紋理按可視區(qū)域只畫可見的塊視錐裁剪要么把原始QImage拆成金字塔縮放級(jí)別切換時(shí)換用不同分辨率的紋理顯存占用能壓下來(lái)一大截。這兩條路的共同點(diǎn)是始終保留 CPU 側(cè)的原始 QImageGPU 上的紋理只是顯示用的副本任何需要精確像素的操作取色、測(cè)量、導(dǎo)出都回到原圖算不要從紋理讀回來(lái)。關(guān)于驗(yàn)證我的習(xí)慣是準(zhǔn)備一組刁鉆圖當(dāng)回歸樣本一張 1×1、一張 1023×769寬度不是 4 的倍數(shù)、一張帶 alpha 的 PNG、一張 20000×20000 的大圖、一張灰度圖。每次改完矩陣或者紋理上傳邏輯就把這五張挨個(gè)過(guò)一遍縮放拖到 0.05 和 30 兩個(gè)極端右鍵轉(zhuǎn)兩圈看有沒有抖動(dòng)、有沒有黑邊、邊緣有沒有斜紋。這套流程是被坑出來(lái)的血淚經(jīng)驗(yàn)——只測(cè)一張 4K 的彩色 JPG永遠(yuǎn)發(fā)現(xiàn)不了對(duì)齊和格式的問(wèn)題。從那以后我每次動(dòng)渲染相關(guān)的代碼都會(huì)在提交前把這組圖跑一遍寧可多花十分鐘也不想再收到大圖打開是斜的這種沒有截圖、沒有復(fù)現(xiàn)步驟的反饋。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
99热精品在线| 天天综合91| 国产精品高潮呻吟av久久4虎| 亚洲免费成人在线高清无码视频 | 91视频观看网站| 中文区中文字幕免费看| 日本高清久久| 加勒比无码毛片| 亚洲91在线播放影院| 色妹子A V| 嗯嗯啊啊视频一区二区三区| 中文字幕日韩电影人妻| 台湾佬中文娱乐自偷自拍| 久久大香蕉97| 人妻天堂综合网| 久久粉色| 91无码中出人妻视频| 欧美啪啪天堂| 91在线色综合| 唯美清纯 妖精视频| 色欲久久综合| 综合色欧美| 色狠狠综合| 啊啊啊不要啊啊受不了了视频在线 | 日韩性爱1级片视频| 天天狠| 久久亚州大香蕉| 国产成人在线观看综合| 青青操日韩| 亚洲啪啪性视频| 久久熟女嫩草成人片免费| 男人a天堂手机在线版| 国产真实野战在线视频| 国产人人干| 亚洲九月丁香| julia国产在线| av网页一区二区三区| 天天超级碰碰碰| 午夜影美女日鸡鸡天天视频国产| 蜜桃久久精品一区二区三区| 欧美久久伊人| 国产成人精品网站| 亚洲色图 欧美热图 清纯唯美 另类自拍| 欧美色图电影| 久久欧洲| 无码在线亚洲| 大香蕉中文| 国产精品高潮久久AV| 免费中文综合精品| 中文字幕第23区| 欧洲一级性爱视频在线观看| 青草精品视频一日本久久久久网站| 国产精品亚洲一区二区三区四区| 热热色91| 久久久久久9999| 国产超碰| 极品少妇久久久| 欧美综合骚| 国产肏逼网站| 国产中文字幕在线观看| 综合免费无码中文| 国产精品成人AV片免费看网站| 97超视频在线观看| 色玖玖| 麻豆视频国产一区二区| 九九人妻| 精品久久在线区一区| 精品无码久久久久久国产浪潮| 久久夜精品一区二区三区| 免費黃色視頻觀看一| 97天天综合| 91熟女综合| 色色色色综合网| 九九碰九九爱97超| 北京美女一区二区| 久久精品国产精品亚洲艾通辽熟妇 | 久久九九一区二区三区成人| 久久 精品| 亚洲色91C| 超碰在线成人| 人人摸.人人色| 情色五月天就去干| 伊人成人情色综合| 超碰97起碰| 在线色导航| 友优传媒精品在线一区二区| 9长久久精品| 99综合网| 偷窥自拍亚洲天堂网爆| 少妇一级婬片免费放一级a性色.| 俞拍久久国应视频| 啊啊啊啊啊啊啊在线| 国产成人欧美精品在线| 成人久久无码www| 中日高清无码操逼视频| 久久伊人亚洲AV无码网站| 香港久久久| 国产成人资源| 亚洲 日本 一 二 三| 2019久久久久久久久福利| 麻豆亚洲AV成人无码久久精品| 日韩久久艹| 亚洲人成网www| 无码精品久久久久久亚洲| 日韩av色图| 超碰资源亚洲97| 国模精品一区二区三区苹果色戒 | 伊人麻豆传媒| 日韩无码服务区| 男人的天堂2000| 国产白嫩精品久久| 99热这里只有精品99| 亚洲高清国产理伦片| 久久在线观看免费视频| 清纯唯美亚洲综合| 欧美日韩亚洲天堂| 欧美第二页| 国产精品一区在线播放| 成人资源中文字幕在线观看| 久久人妻一区二区三区高清| 色九九九综合| 国产精品欧美激在线| 宅男91视频在线播放| 99在线免费观看| 深夜国产一区二区三区在线看| 国产婷婷综合在线观看| 日韩精品一区二区人人人| 九一性生活免费视频| 97碰碰日本乱偷人妻中文的| www.高清无码诱惑一区.com| 97超碰巨乳| 久久这里精品国产99丫e6| 久久久久成人蜜桃精品| 亚洲丁香花色| 欧美少妇一区二区三区| 极品粉嫩一区二区| 欧美高潮在线| 日日骚精品视频| 亚洲资源网| 天美传媒av一区二区| 国产一| 91欧美巨乳| 精品999日本| 日本三级韩国三级美三级91| 欧洲一区二区| 亚洲毛片基地专区| 国产精品亚洲一级av第二区| 久草免费福利在线播放| 日韩不卡在线一区二区| av大香蕉| 国产天天骚| 性感女人网页在线观看视频| 亚洲一二三四区机械| 国产性感在线观看| 国产情色第一第二页在线观看| 在线情色电影 91大 | 欧美激情性久久久久久| 性爱av网站| 五月丁香在线| 一区二区三区日韩欧美| 欧美国产操逼| 99国产精品| 欧美精品23| 午夜久久无码1000合集| 亚洲无码99| 欧美少妇一区二区三区| 亚洲天堂美臀在线| 国产激情在线| 日韩精品一二三| 亚洲色人| 欧美大香蕉同搞| 日本一级性爱| 丝袜喷水在线| 欧美后入视频| 美女诱惑久久| 狼狼色丁香久久婷婷综合五月| 久草福利在线资源站| 99综合| 欧美激情欧美精品| 国产视频97| 涩涩涩综合| 动漫爆乳3D奶水一区在线观看 | 中文字幕在线第二页| juliaann欧美丝袜办公室| 国产福利电影| 337p大胆噜噜噜噜噜91Av| 天天透伊人| 97色妞| 激情小说激情视频| 国产自制av蜜乳| 亚洲字幕一区二区| 91在线限制级| 久久精品一区二区一8| 亚洲强奸乱伦影视网| 狠狠中文字幕| 久久精品国产99久久,亚洲日韩久久日本一区一区三区 | 欧美色图91| 色综合久久av| 青青操青娱乐| 91痴汉| Sekablack无码一区| 九九黄色网| 欧美日韩青操| 国产高清在线观看欧美| 欧美一二三区四五区| 欧美第五页| 中国操逼无码| 激情一区二区三区在线观看| 色综九九九一区| 中文字幕精品一区欧美| 国产美脚女优尤物在线观看| 久久久久白虎| 欧美成人黄网色网站| 日本一区二区电影网站| 久久大陆| 欧美经典一区二区三区| 综合色拍| 93人人操人人| 国产欧美日韩臀| 日本一二区不卡| 国产女性无套 免费观看| 青青草乱入乱欲视频在线观看| 欧美色图 色综合图| 欧美国产伊人久久久久| 亚洲情色在线| 久久透逼视频| 人人澡综合涩| 51国产午夜精品视频| 蜜臀久久久久久999| 中日韩久久久免费看| 逼操网站| 亚洲欧美91√| 国产区性爱在线视频秋霞豆| 91精品婷婷国产综合久久竹菊| 2024黄色视频| 中美日韩毛片| 中日韓欧美高清| 69精品人人人人| 中文字幕午夜精品久久久| 国产精品久久久久久片| 欧美天堂第二区| 亚洲蜜乳av| 亚洲另类综合欧美| 操逼操逼操| 韩国久久97| 97超碰色色| 亚洲天堂区| 欧美97在线欧| 国产黄色动态精品| 东京热一区二区中文字幕| 久久久久久国产精品免费网站| 国产白丝在线| 日韩丝袜二区| 国产精选视频| 亚洲欧洲小说图片视频| 日韩免费中文字幕视频| 久操操| 久久国产热视频97电影| 精品国产乱码久久久久久免费| 女人爽到高潮潮喷18禁网站| 欧美精品庄| 色嘟嘟人妻天堂网| 久久天天艹| 欧美色图片91| 两女互慰AV高潮喷水在线观看| 热久日综合| 5278欧美一区二区三区| 清纯唯美综合亚洲| 骚货人妻偷情自拍在线视频| 国产福利一区二| 精品美女少妇一区二区三区| 国产一区在线观看无码AV| 日日日日做夜夜夜夜做无码97| 欧美性生活综合| 色欧美亚洲| 成人天天看站长推荐| 四虎影视永久在线免费| 青青草原香蕉日本Ap| 97久久资源| 国内偷自视频区视频综合| 伊人久久亚洲色欲综合网站 | 丰满翘臀美女影院视频| 欧美性生活免费网| 天美传媒麻豆一区二区三区国产精| 亚洲丝袜色| 久久久久久性爱免费视频| 日韩AV色图| 综合久久六月久久婷婷| 国产精品香蕉| 91精品又粗又猛又爽| 97五月天| 丰满岳乱妇一区二区三区| 久久九九精品一区二区| 亚洲精品一区中文字幕乱码| 日本三级A片网站com| 天美传媒精品久久视频| 屌妞视频久久久久久久久久久久| 婷婷丁香在线| 99国产在线 精品 视频| 欧美激情久操网| 亚洲综合小视频小说在线观看| 激情综合婷婷| 国产操操日韩三级黄| 国产精品国产精品国产| 97av,com| 久久本道| 天天综合色| 日本免费一级AAA大片器| 欧美色性情| 91欧美综合在线| 麻豆2区1区天美| 国产精品嫩草影院免费| 性爱综合一区二区| 国产综合久久久麻桃个| 91狠狠狠| 伊人亚洲综合| 久久久久久亚洲精品中文字幕人妻| 国产精品毛片?v一区二区三区| 91老司机精品| 欧美极品色| 78久久久| 亚洲情色1区| 色婷婷五月综合激情中文字幕| 久久春色| 一区二区不卡视| 欧洲一区二区三区四区在线观看| 久久久久一本一区二区青青蜜月| 精品久久久九九九孕妇| 大香蕉啪啪啪| 国产精品探花色| 中文字幕在线免费观看 | 天天综合香 ld视频| 久久人妻丝袜一区二区三| 浪人综合网| 午夜αv| AV女资源| 殴美色网| 亚洲人综合19| 97久久超碰日韩精品| 91国产丝袜美女| 又摸又舔在线观看网站| 欧美久久婷婷| 人妻熟女一区二区三区在线| 99在线视频播放| 另类亚洲图色| 啊啊啊在线观看免费视频| 欧美熟妇精品黑人巨大一二三区| 青青草吊丝| 大香蕉伊人亚洲| 欧美天天拍| 女人被添高潮免费视频| 日韩午夜啪啪视频| 99热18| 婷婷五月天激情网| 婷婷成人五月天| 99色色网| 久久9精品视频| 91精品电影18| 欧美色66| 91欧美综合在线| 蜜桃臀久久| 久久人体一区二区| 久久久久久人| 成年人免费观看网站| 人妻丰满熟妇av无码区蜜桃| 性感美女91影视| juliaann丝袜| 麻豆久久一区二区三区| 99久久精品欧美国产| 一个色导综合| 欧美日韩激情无码专区| 操操操五月天婷婷丁香影院| 国内亚洲精彩视频在线| 天天综合站| 日本在线15p| 91热| 久久亚洲国产成人| 黄片aaaaa一区| 啊v视频在线观看| 大香蕉乱伦视频网| 色哟哟-国产专区| 骚熟女吞| 欧美图片校园春色| 大肥女高潮bbwbbwhd视频| 国产h小视频在线观看免费| 日韩欧美大片免费高清啪啪| 欧美亚洲另类在线蜜桃| 九九热精品| 伊人色综合超碰| 伊人 俄罗斯 a v| 新怡红院| 美国黄片aaa| 国产强奸超碰AV| 欧美精品自慰系列寂寞少妇| 啊a一区在线| 精品无码一区二区人妻久久蜜桃| 中文字幕黄色一起草| 国产精品女aA片爽爽视频| 成人亚欧免费视频| julia高潮后不停追击中出| 五月丁香综合啪啪| 久久人妻无码毛片A片麻豆| 天美av在线| a片 xxxx受爽视频| 黑人精品成人一区二区三区| 后入 亚洲 美女 射| 亚洲 综合 第一页| 男女无套 免费网站| 久久久久久国产精品免费网站| 亚洲婷婷五月天| 日韩伦理视频| 97国产|免费| 91人妻精华帖| 天堂资源欧美| 亚洲一区二区av| 一本久道在线综合视频| 98色网| 国产视频大全| 日本操逼视频免费| 夜夜操二区| 97就爱干| 天天搞欧美| 亚洲第一页第二页激情| 亚洲欧综合另类无码一区| 97色伦欧美| 啊啊啊好多水| 在线亚洲精品久久久| 国产一区二区精品久久99| 超碰午夜| 思思99热| 乱论91| 日韩日韩日韩-国产乱码精品一区二区| 日韩国产中文字幕| 中文?日韩?免费?精品| 青青草白白色| 五月丁香在线| 青青操在线视频| 色婷婷导航| 啊啊啊啊在线播放| 色综合久| 为用户提供免费看黄网址在线观看| 欧洲与亚洲欧美精品中文字幕| 欧美不卡二区| 精品少妇99| 天天日天天射天天干| 国产强奸超碰AV| 青青草久草| 人妻内射一区二区在线视频| 色婷婷激情| 久久久一区二区三区三州| 夜夜爽夜夜摸夜夜操免费视频| 国产精品交换一区二区| www.av在线视频| 欧美色网络| 最新中文字幕av| 亚洲超碰在线| 欧美日韩*字幕一区| 九九九九精品一区| 涩五月婷婷| 可能人人看人人摸| 色综合一本| 亚洲情色 自拍| 欧美性爱网97| 大香蕉伊人一区在线观看| 96久久精品一二三区色欲| 2017天天插| 天天躁狠狠躁av| 亚洲欧洲网站免费观看| www国产无码| 青青操在线视频| 岛国999| 国产婷婷一区| 九色 人妻 大香蕉| 日本九九九九| 国产中文字幕在线点播| 黄色视频高清无码网站| 青青五月天| 国产精品粉嫩福利在线| 99热99在线| 九九久久一区二区伦理| 极品综合| 欧美日韩大黄片| 碰碰97| 九九九九九精品视频| 91无摭挡| 激情五月天校园春色网| 天美传媒AV国产在线| 热天堂一区二区| 激情自拍 校园春色| 久久久国产亚洲精品系列| 国产精品视频91久久| 国产欧美另类久久久精品课程| 啊啊啊啊啊好舒服视频| 精品视频久久区| m欧洲一级午老| 国产超碰国产97| 精品久久視頻在线| 亚洲色图激情小说| 在线观看十八禁| 偷拍伦理视频| 自偷自拍的亚洲视频| 欧美一级黄片免费播放| 女人被添高潮免费视频| 一级A啪啪啪啪| 久久婷婷色| 久草五月| 日本熟妇熟色97一本在线观看| 亚洲欧洲偷拍一区| 麻豆久久久久久久久丝袜| ,国产乱人伦精品一区二区三区| 亚洲丝袜色| 欧美成人9797| 黄网在线播放| 中出91| 78p欧美| 精品无码一二三四区| 日本一二区免费| 综合久欧洲| 精品无码人妻一区二区免费蜜桃| 精品少妇人妻| 夜夜嗨TV| 国产色图乱伦| 人人操人人插人www| 手机在线视频国内精品| 婷婷丁香熟妇综合网| 色色五月天婷婷| 欧美黄色图片| 啊啊啊啊好疼视频| 超碰免费人妻在线| 欧美,日韩综合久久| 国产成人精品日本视频| 99只有精品| 人妻精品一区二区全免费| 精彩国产视频播放1区2区| 久久亚码| 清纯唯美亚洲综合| 豆花视频操逼网址| 欧美性生活综合| 丰满翘臀美女影院视频| 色麻豆AV| 超碰人妻久久| 国产强奸超碰AV| 欧美大码在线视频| 中文字幕精品三级久久久| 夜夜欢天天干| 日欧操屄| 韩国黄片aaaa| 欧美日韩国第一区| 风间由美日韩欧美久久| 无码久久亚洲高清,| 无码精品蜜桃一区二区三区ww| 日本有码久久| 精品网站99999| 精品传媒在线一区| 手机在线看片免费人成视频| 97国伦国色| 九t超碰| 日本狂喷奶水在线播放212| 中文字幕五区| 日日噜噜夜夜久久亚洲一区二区 | 五月丁香六月综合缴清无码| 超碰在线成人| 97久久天天综合色天天综合色电影| 啊啊啊啊啊啊在线观看| 凹凸视频特色日本特黄| 夜夜操一区二区| 99精品国产户外露出| 97在线视频观看| 色香欲天天天天综合色| 中文字幕精品一区二| 伊人久久88国产女| 福利五区| 草草网站影院白丝内射| 日韩有码一区三区| 无码人妻精品一区二区三区九九| 3PAV乱伦视频| 亚洲有薄码区日本系列中文字幕| 熟人人妻少妇精品久久| 一级岛国大片| 欧亚乱色熟一区二区三四区| 999热这里只有精品| 国产极品精品美女视频| 91天天综合网,天天综合网| 又大又大又大又粗爽高潮观看| 欧亚在线视频| 加勒比色99999| 亚洲一区日韩| 日韩精品资源| 久久精品国产亚洲AV嘿嘿| 乱码熟妇人妻久久久| 香蕉国产精品麻豆亚洲欧美日韩| 后入 亚洲 美女 射| 亚洲 在线| 欧美精品成人亚洲| 国产乱伦视频污| 激情网五月天| 九九热精品| 91色情黑丝搞鸡在线观看一区二区三区三州| 999久久芭蕾| www欧美性爱| 亚州色图欧美色图| 婷婷综合久久| 日韩大香蕉| 99re不伦| 激情五月天插| 一区二区不卡| 最新中文字幕在线亚洲| av橘色网站| 欧美色婷婷| 四虎免费在线观看| 欧洲中文字幕| 国产一在线观看| 日本精品一区二区三| 无码国产精品午夜不卡(| 蜜臀AV一区二区三区| 91大学精品激情戏| 国产黄色在线播放观看| 色女99一级片在线观看| 色网在线视频观看免费| 国产精品夜夜夜| 另类小说五月天| 亚洲欧美天| 精品女人999| 久久久久久久9| 欧美大码在线视频| 岛国大片国产| 国产精品农村妇女精品| 欧美另类色图片| 国产黄色在线播放观看| 热热色国产一二区AV| 夜夜操二区| 久久久久久久九九九九九九| 久久精品一区二区三区蜜桃臀| 99热这里只有精| 被窝影院午夜看片无码| 久久 久久国内精品亚洲| 99在线免费观看| 伊人久久在线视频观看| 欧美综合色,www| 狠狠夜色午夜久久综合在线| 欧美性爱伊人| 99久国产精品午夜性色福利| 午夜噜噜噜| 加勒比AV网| 色色色99| 成人羞羞视频国产| 亚洲AV不卡在线观看| 亚州成人a∨| 免费自拍三级综合| 麻豆视频一区二区| 久草线上视频免费看| 天天爽爽爽爽| 亚洲图片偷拍视频区| 国产二区三区免费视频| 天天天做天天天爱天天天爽| 亚州色图狠狠干| 97在线精品| 精品日韩| Aa东京男人的天堂| 色av中文字| AV天堂国产| 欧美草草高清日韩视频| 在线天堂999| 九九色热| 18禁免费视频| 在线 欧美 亚洲| 久久久不卡区一区二区三区久久久| 超碰在线91| 逼逼逼逼操操操操操操操操操午夜剧场 | 免费精品福利在线观看| 久久久久亚洲AV无码专区少妇| 婷婷爽人人婷婷爽视频| 亚洲综合色图欧美| 肉丝中文无码高清| 精品中文日韩字幕视频| 亚洲黄日韩无码专区| 开心五月激情网| 欧美亚洲中文字幕| 亚洲精品亚洲人成在线麻豆| 襙一襙| 黑人免费福利视频| 日韩一级二级三级免费看完整版| 亚洲丝袜少妇在线| 加勒比99999| 青木玲在线不卡| 精品96久久| 欧美午夜精品久久久久久3D| 免费看欧美美女黄色大片| 3028国产精品| 五月丁香黄色网| 91人妻在线视频| 校园春色亚洲无码| 国产精品肉丝自拍| 日本午夜久久电影| 啪啪91| 九九热精品| av天天在线观看| 大香蕉操久久| 免費黃色視頻觀看一| 久久久久久AV无码免费网站| 久操精品网| 日韩性爱电影一区| 久久久国产三级黄色片| 五月婷婷综合网| 懂色中文一区二区三区| 国产成人亚洲精品无码最新在线| 富女玩鸭子一级毛片| CCYY草草影院地址入口| 370p日韩欧美亚洲精品| 成人5码视频| 欧美 亚洲 偷拍自拍| 国产成人综合网| 久久老子无码午夜伦不卡| 大色综合网| 成年人三级黄色片视频| 丰满高潮18xxxx| 99精品在线播放| 欧美乱色| 97视频900| 超碰97人人乐| 秋霞午夜成人福利片片| 啊啊啊操死我| 欧美大香蕉同搞| 精品国产肉丝袜在线拍国语| 91爽啪| 香港日本韩国人妇99www.wccm20| 伊人久久亚洲色欲综合网站 | 国产高清午夜成人在线观看| 成年人黄色小视频网站| 五月天丁香婷婷综合网站| 色综合久久888| 日本熟人妻中文字幕在线|...久久国产精品-国产精品_日本一区二区三区中文字幕 | 嗯嗯嗯啊啊在线观看| 91色婷婷综合久久中文字幕二区| 天天看精品动漫视频一区| 无码人妻精品酒店| 在线免费观看高清无码视频| 99久久婷婷丁香| 久夜视频| 欧美gv在线观看| 久久精品国产免费观看99| 熟女丝袜视频| 国产精品乱码久久久、久久| aaa淫乱视频| 久久久天堂| 亚洲男人在线观看天堂| 精品国产一区二区三区四区在线看| 精品人妻中文字幕4399| 91麻豆va国产精品| 欧美少妇第一页| 国产搭汕a级片| 福利社区午夜一区二区| 久久超碰久| 99精品丰满人妻无码| av一区二区三区不卡| 69少妇一区二区| 久久久久久精品免费看A级| 亚洲国产欧美日韩精品一区二区三区,国产一区二区三区在线看片,欧美性猛交 XXX | 久久AV色| 91狠狠综| 婷婷五月激情综合| 欧美色图人妻| 国产精品久久| 日本黄 R色 成 人网站| 亚州熟妇精品| 日韩日本欧美在线观看| 99热综合| yazhouzaixian| 国产精品无码av| 中文字幕av久久爽Av| 96久久久久| 婷婷久久五月| 我爱搞逼综合网| 国产综合色精品在线观看| 色婷婷网| 偷拍亚洲情色| 蜜臀AV秘一区翔田千里| 久久久999日本大片| 久久久555| 乱欲一区二区| 嗯啊不要啊在线 | 久操网线| 一起草AV| 欧美 亚洲精品首页| 国产精品久久久久中文字幕| 亚州情色j区| 亚洲激情在线| 91九九| 97就爱干| 国产家庭乱伦网址| 亚洲天堂电影网| 伦伦成年午夜免费视频| 操逼网免费无码视频| 国产又长又大又粗的视频| 91爆操视频| 91处女在线视频| 国产精品自在自拍视频| 亚洲诱惑天堂 | 69综合网| 色在线综合| 欲香欲色天天天综合和网| 免费无码国产精品v片在线观看| 黑人无码一区二区| 欧美日韩国产精品久久色婷婷| 久久国内| 综合熟妇一区二区三区| 超碰人人干| 久久大陆| 国产成年精品高清在线观看91| 啊啊啊啊啊啊啊国| 9久在线视频只有精品| 99re69综合| 91久久国产精品| 日韩不卡a级视频专区| 加勒比五月天| 亚洲欧美精品福利在线| 中文字幕一区二区无码成人| 91黄射| 99色热国产视频精品| 人妻少妇久久| 91亚·色| 懂色av色欲av蜜臀av| 中国韩国明星一极片一区乱码毛片人妻熟女一区二区三区 | 97视频网站| 久久久久国产| 久久黄黄| 亚洲午夜福利在线影院| 欧美亚洲小说| 加勒比av官网在线| 国产农村妇女一区二区| 欧美成人一级免费电影| 天天综合网91| 国产精品3| 江都AV在线| A片三级无码| 男女做爰猛烈动高潮A片免费应用 少妇厨房愉情理伦片bd在线观看 不卡中文字幕aⅴ在线 | 伊人黄色片| 狠狠躁伊人中文字幕| 亚洲中文字幕日产无码久久| 色人久久| 亚洲毛片一级带毛片基地| 亚洲日韩天堂| 日夜尻逼网| 欧美在线啊啊啊| 日韩欧美视频青青| 久久久久久久国产视频| jazzjazz国产精品麻豆| 大茄子熟女AV导航| 青青伊人加勒比海| 一本正道久久熟女| 91精品综合久久久久久五月丁香| 精品九九国产无码| 性天堂| 色图四区| 桑老女人九区| 人妻少妇三级| 久久久久久久久久久97| av九九| 综合欧美日韩在线观看| AV一区观看| 呦呦影院| 97日韩欧美| 大逼色网站| 青青草华人在线欧美在线| 婷婷色网| 欧美色997| 91逼逼女人91| 97天天搞在线| 清柠毛片| 色婷婷五月天| a久久| 97人人草| 激情五月婷婷综合| 97色干| 人妻人人操| 粉嫩绯色AV一区二区在线| 中国大陆国产高清AⅤ毛片| 国产无码精品高清| 91精品微拍福利| 三级日韩一区二区三区| 亚洲欧美国产va在线播放频| 亚洲欧美综合| 97综合久久| 日本一区二区中文字幕久久| 97在线免费| 超碰欧美| 亚洲天堂在线怕怕视频| 一级人妻性爱视频| 中字幕人妻一区二区三区| 欧美性生活男人的天堂| 在线观看不卡一区二区三区| 乱伦日本中文自拍| 国产精品麻豆免费视频| 国产家庭乱伦性爱视频| 久操网无码在线| 国产熟女完整版中字| 日韩精品 视频一区二区| 日本女优在线视频福利| 日本精品成人无码| 婷婷五月影院| 亚洲综合97中文网| 日本精品国产视频| 亚av顶级裸体一区二区三区四区五区| 蜜臀久久99精品| 99热国产| 日韩性色| 国产亚洲福利第一页丝袜| 国产一区二区三三视频| 亚洲精品国产熟女久久久久久| 欧美强奸乱能| 91九九| 操人妻丝袜高跟| 大香蕉在线免| 夜夜爽夜夜摸夜夜操免费视频| 亚洲,欧美,综合网| 亚洲天天更新| 久久免费99精品久久久久久| 亚洲精品啪视频| 色99在线| 亚洲精品天天影视综合网 | 好爽免费视频,| 欧美九九九| 欧美精品成人一区二区在线观看| 欧美午夜视频免费观看| av婷婷色婷婷色六月| 人妻少妇视频在线播放| 白丝少妇一区二区| 后入综合久久| 亚欧高清| 第一高清av中文字幕| 综合国产97| 91精品少妇搡搡搡| 亚洲欧美综合| 韩国午夜理伦三级好看| 五月婷婷色| 裸体美女久久久| 亚洲熟女综合网| 国产自产自拍| 天天透伊人| 超碰97在线中文| 老司机福利青青草| 极品白嫩美女白浆成人福利在线看| 欧美色偷拍| 蜜桃臀AV在线| 老司机深夜18禁污污网站| 啊视频在线| 九九九影院| 狠狠超| 在线观看日韩av不卡| 黄色高清久久无码依人| 97色操| 青青久久手机线视频| 97精品一二区| 9美女超碰在线免费观看| 熟妇xxxxx性春色| 日本一本一区二区三区四区五区欧美日韩中文字幕 | 九九十八精品| www亚洲欧美| 亚欧Av| 超碰在线97国产| 东京热一区二区中文字幕| 亚洲AV成人无码久久精品播放| 97玖玖超碰| 久久久夜夜夜| 国产精品青草综合久久| 成人在线午夜视频一区| 美女裸体无遮挡永久免费观看网站| 国产精品视频精品一二| 熟女网站最新| 老熟女乱伦一区| 啪啪视频mP4| 国产精品网址| 五月丁香六月婷综合成人综合| 超碰久在线天天做| 国产精品日韩在线一区| 1024亚洲中文字幕久在线看片你懂的| 亚洲天堂少妇| 女人喷水视频在线观看| 人人爽人人精品乱人伦AV| 久久久久久久久久va| 九久久九精品视频| aa片毛片| 99国内精品| 亚洲色人| 偷拍欧美激情| 中文字幕丰满子伦无码专区在线视频最新| 激情丁香五月婷婷| 欧亚 另类 久| 天天躁日日躁AAAXX| 丝袜美腿91| 一级免费啪啪片| 久久九九久精品国产尤物|国产精品爽黄69天堂A片潘金莲,国产亚洲精品第一综合 | 天天综合网亚洲综合网| 播播亚洲小说亚洲| 污电影在线观看| AV无码久久久精品| 久久精品99| 成人性爱高清视频免费看| 国产AV人人夜夜澡人人爽麻豆| 欧美日韩在线国产在线| 亚洲天堂电影网| 国产精品无码在线| 一级免费精品| 日韩婷婷| 91天堂| 97精品一二区| 日本一区二区三区午夜观看| 97色诱| 色婷婷激一区二区三区| 久久久久久久久久久久欧美日| 亚洲欧美在线观看免费| 久久高清无码夜夜操| www黄片免费看com| 东京热,男人的天堂| 韩日精品四区| 日韩兔费看黄片| 欧洲乱码视频| 大香蕉强奸乱伦| 久久精品国产97欧美精品亚洲 | 人妻铁牛TV| 国产精品午夜成人福利| 午夜啪啪片| 小电影欧美91| 中文字幕精品人妻丝袜| 国产女同视频在线播放| 蜜臀久久精品久久久久视频| 久久丁香五月婷婷| 天天激清| 欧美色图人妻| 一起草av| 无码人妻精品一区二区三区99不卡| 免费成人在线熟妇网| JULIA一区二区三区在线播放| 久久人| 98精品国产乱码久久久久久| 在线v中文字幕一区二区三区 | 中文字幕av一区二区三区人妻少妇 | 蜜臀在线免费观看在线免费观看| 国产精品亚洲一级av第二区| 肉丝中文无码高清| 麻豆视频test| 嫩草影院性色| 97色碰| 九九人妻| 9久久9综合| 91精品人妻电影| 亚洲色欧美| 久久久久久裸体| 伊人97色天使| 国产精品熟女丝袜一区二区| 人人爱人人乐人人操| 99re热| 中文字幕一区 二 区 三 四 五 区日 日 骚 | 99色热| 中文字幕乱碼在线| 强奸a片网| 成人自拍三级在线观看| 91热热色| 欧美日韩国产人人| 亚洲一区二区三区久久 亚洲一区二区| 国产精品亚洲一级av第二区| 国产免费内射视频| 色制服丝袜夫妻av一区| 青青草九九九九九| 探花激情视频| 亚洲三区视频| 97超碰色色| 久久激情视频| 色综合久久夜色精品国产天堂| 91精品综合久久久久久五月丁香| 久久av一级av少妇av高潮| 欧美另类综合久久| juliaann精品熟女一区| 夜夜嗨一区| 婷婷久草一区二区三区| 亚洲成?V人片在线观看福利| 一区二区国产视频在线观看| 国产一在线观看| 91w欧美| 欧美色91| 久久久91福利姬| 九九拍拍精品视频在线播放 | 天天视频黄| 国产美女自拍视频| 大香蕉性欧美| 天天操天天日青青草超碰av| 精品无人区麻豆乱码久久久| 亚洲精品色| 性爱av网站| 久久久免费的精品| 久久国产乱子伦精品免费女人| 另类图片综合| 亚洲小说视频| 欧美午夜熟妇黑人精品91| 四虎在线免费视频| 60秒免费视频| 国产亚洲日本| 夜精品久无码| 九九夜精品九九在线| 久久久久久久78| 嗯嗯啊啊用力视频免费| 91久久精品国产| 色香阁在线| 91网站18在线观看| 中文高清一区二区的| 狠狠干,狠狠操| 五月天激情小说| 九九碰九九爱97| 九九AV| 99热这里| 97精品国产97久久久久久| 国产刺激视频| 亚洲熟妇自偷自拍另欧美| 激情久久久| 日韩三级视频一区二区三区| 欧美日韩国产在线| 日韩免费中文字幕视频| 国产一区二区视频在线播放| www黄片免费看com| 成人免费福利网站国产| 国产激情在线| 国产精品久久久久综合| 亚洲国产成人高清在线| 99人人干| 国产91美女高潮| 高清不卡视频| 亚洲黄日韩无码专区| 少妇三P| 狠狠躁天天躁日日躁| 亚洲91综合| 99久久久| 欧美色图片| 最新av网站在线观看| 乱伦3P视频| 亚洲色综合| 熟妇人妻一区二区| 亚州 综合 色图| 夜夜精品视频一区二区| 啊啊啊啊好疼| 91精品国产91久久福利| 影视综合无码少妇| www.国产高潮精品| 欧美成人精品A片免费一区99| 91超碰人人| 都市激情人妻一区二区青青操视频 | 中出91| 91最新综合| 九九九九九九九| 美女91在线| 北约熟女超碰| 五月婷丁香| 亚洲永久AV无码精品秋霞| 在线五区| 东北女人无套内谢视频| 一级aaaaa欧美中文字幕录像片| 91色色色| 久久久久久91香蕉国产| 人妻喷水| 伊人一级免费黄片| 5278欧美一区二区三区|