├── .clang-format ├── .gitattributes ├── .github └── workflows │ ├── android.yml │ ├── ios.yml │ ├── macos.yml │ ├── ubuntu.yml │ └── windows.yml ├── .gitignore ├── Common ├── Common.pri ├── GLCommon.cpp ├── GLCommon.h ├── GLWindow.cpp └── GLWindow.h ├── DepthTest ├── DepthTest.pro ├── res │ ├── image │ │ ├── cube.png │ │ ├── cube1.png │ │ └── w1.png │ ├── shader.qrc │ ├── shader │ │ ├── fshader.glsl │ │ ├── singleColor.glsl │ │ └── vshader.glsl │ └── texture.qrc └── src │ ├── cube.cpp │ ├── cube.h │ ├── floor.cpp │ ├── floor.h │ ├── main.cpp │ ├── window.cpp │ └── window.h ├── FrameBufferObject ├── FrameBufferObject.pro ├── res │ ├── img.qrc │ ├── img │ │ └── s.jpg │ ├── qml.qrc │ ├── qml │ │ └── main.qml │ ├── shader.qrc │ └── shader │ │ ├── fragment.glsl │ │ └── vertex.glsl └── src │ ├── easy.h │ ├── item.cpp │ ├── item.h │ ├── main.cpp │ ├── render.cpp │ └── render.h ├── GLSL.pro ├── HelloCube ├── HelloCube.pro ├── res │ ├── image │ │ ├── cube.png │ │ ├── cube1.png │ │ └── w1.png │ ├── shader.qrc │ ├── shader │ │ ├── fshader.glsl │ │ └── vshader.glsl │ └── texture.qrc └── src │ ├── cube.cpp │ ├── cube.h │ ├── main.cpp │ ├── window.cpp │ └── window.h ├── HelloFBO ├── HelloFBO.pro ├── res │ ├── image │ │ ├── cube.png │ │ ├── cube1.png │ │ └── w1.png │ ├── shader.qrc │ ├── shader │ │ ├── fFbo.glsl │ │ ├── fshader.glsl │ │ ├── vFbo.glsl │ │ └── vshader.glsl │ └── texture.qrc └── src │ ├── cube.cpp │ ├── cube.h │ ├── main.cpp │ ├── window.cpp │ └── window.h ├── HelloMix ├── HelloMix.pro ├── res │ ├── img │ │ ├── bj.jpg │ │ ├── ha.png │ │ └── pu.png │ ├── res.qrc │ ├── shader.qrc │ └── shader │ │ ├── fragment.fsh │ │ └── vertex.vsh └── src │ ├── main.cpp │ ├── window.cpp │ └── window.h ├── HelloTexture ├── HelloTexture.pro ├── demo.png ├── res │ ├── image │ │ ├── w1.png │ │ ├── w2.png │ │ └── wood.jpg │ ├── img.qrc │ ├── shader.qrc │ └── shader │ │ ├── fragment.fsh │ │ └── vertex.vsh └── src │ ├── main.cpp │ ├── window.cpp │ └── window.h ├── Instance-Texture ├── Instance-Texture.pro ├── main.cpp ├── mainWindow.cpp ├── mainWindow.h ├── pu.png └── res.qrc ├── Instance ├── Instance.pro ├── main.cpp ├── mainWindow.cpp └── mainWindow.h ├── Instance2 ├── Instance2.pro ├── main.cpp ├── mainWindow.cpp └── mainWindow.h ├── LICENSE ├── QuickOpenGL ├── QuickOpenGL.pro ├── deployment.pri ├── res │ ├── img.qrc │ ├── img │ │ └── s.jpg │ ├── qml.qrc │ ├── qml │ │ └── main.qml │ ├── shader.qrc │ └── shader │ │ ├── fragment.fsh │ │ └── vertex.vsh └── src │ ├── main.cpp │ ├── shader.cpp │ └── shader.h ├── README.md ├── SkyBox ├── Assets.qrc ├── SkyBox.pro ├── assets │ ├── back.jpg │ ├── bottom.jpg │ ├── cube.png │ ├── front.jpg │ ├── left.jpg │ ├── right.jpg │ └── top.jpg └── src │ ├── Cube.cpp │ ├── Cube.h │ ├── GLHeaders.h │ ├── SkyBox.cpp │ ├── SkyBox.h │ ├── TWindow.cpp │ ├── TWindow.h │ └── main.cpp ├── clang-foramt-All.ps1 ├── img ├── CubeMap.png ├── DepthTest.png ├── FrameBufferObject.png ├── HelloCube.png ├── HelloFBO.png ├── HelloMix.png ├── HelloTexture.png ├── QuickOpenGL.png ├── Renderer.png ├── SkyBox.png ├── light.png ├── lightCasters.png ├── material.png └── mulitLight.png ├── light ├── light.pro ├── res │ ├── image │ │ ├── cube.png │ │ ├── cube1.png │ │ └── pu.png │ ├── shader.qrc │ ├── shader │ │ ├── fshader.glsl │ │ ├── light.fsh │ │ ├── light.vsh │ │ └── vshader.glsl │ └── texture.qrc └── src │ ├── cube.cpp │ ├── cube.h │ ├── main.cpp │ ├── window.cpp │ └── window.h ├── lightCasters ├── lightCasters.pro ├── res │ ├── image │ │ ├── container.png │ │ ├── container2_specular.png │ │ ├── cube.png │ │ ├── cube1.png │ │ └── pu.png │ ├── shader.qrc │ ├── shader │ │ ├── fshader.glsl │ │ ├── light.fsh │ │ ├── light.vsh │ │ └── vshader.glsl │ └── texture.qrc └── src │ ├── cube.cpp │ ├── cube.h │ ├── main.cpp │ ├── window.cpp │ └── window.h ├── material ├── material.pro ├── res │ ├── image │ │ ├── container.png │ │ ├── container2_specular.png │ │ ├── cube.png │ │ ├── cube1.png │ │ └── pu.png │ ├── shader.qrc │ ├── shader │ │ ├── fshader.glsl │ │ ├── light.fsh │ │ ├── light.vsh │ │ └── vshader.glsl │ └── texture.qrc └── src │ ├── cube.cpp │ ├── cube.h │ ├── main.cpp │ ├── window.cpp │ └── window.h └── mulitLight ├── mulitLight.pro ├── res ├── image │ ├── container.png │ ├── container2_specular.png │ ├── cube.png │ ├── cube1.png │ └── pu.png ├── shader.qrc ├── shader │ ├── light.fsh │ ├── light.vsh │ ├── mulitlight.fsh │ └── vshader.glsl └── texture.qrc └── src ├── cube.cpp ├── cube.h ├── main.cpp ├── window.cpp └── window.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | # 关闭格式化 3 | DisableFormat: false 4 | 5 | # 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto 6 | Language: Cpp 7 | 8 | # 标准: Cpp03, Cpp11, Auto 9 | Standard: Cpp11 10 | 11 | BasedOnStyle: WebKit 12 | 13 | # 每行字符的限制,0表示没有限制 14 | ColumnLimit: 160 15 | 16 | # tab宽度 17 | TabWidth: 4 18 | 19 | # 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always 20 | UseTab: Always 21 | 22 | # 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行) 23 | AlignAfterOpenBracket: AlwaysBreak 24 | 25 | #对齐逃脱换行(使用反斜杠换行)的反斜杠 26 | AlignEscapedNewlines: Right 27 | 28 | # 连续赋值时,对齐所有等号 29 | AlignConsecutiveAssignments: true 30 | 31 | # 连续声明时,对齐所有声明的变量名 32 | AlignConsecutiveDeclarations: true 33 | 34 | # 对齐连续的宏定义 35 | AlignConsecutiveMacros: true 36 | 37 | # 对齐尾注释 38 | AlignTrailingComments: true 39 | 40 | # 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似), 41 | # Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似), 42 | # Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom 43 | # 注:这里认为语句块也属于函数 44 | BreakBeforeBraces: Allman 45 | # 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效 46 | BraceWrapping: 47 | # class定义后面 48 | AfterClass: true 49 | # 控制语句后面 50 | AfterControlStatement: true 51 | # enum定义后面 52 | AfterEnum: true 53 | # 函数定义后面 54 | AfterFunction: true 55 | # 命名空间定义后面 56 | AfterNamespace: true 57 | # ObjC定义后面 58 | AfterObjCDeclaration: true 59 | # struct定义后面 60 | AfterStruct: true 61 | # union定义后面 62 | AfterUnion: true 63 | # extern 定义后面 64 | AfterExternBlock: true 65 | # catch之前 66 | BeforeCatch: true 67 | # else 之前 68 | BeforeElse: true 69 | # 缩进大括号 70 | IndentBraces: false 71 | 72 | # 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行) 73 | BreakBeforeBinaryOperators: None 74 | 75 | 76 | # 继承列表的逗号前换行 77 | BreakBeforeInheritanceComma: true 78 | 79 | # 继承列表换行 80 | #BreakInheritanceList: BeforeColon 81 | 82 | # 在构造函数的初始化列表的逗号前换行 83 | BreakConstructorInitializersBeforeComma: true 84 | 85 | # 初始化列表前换行 86 | BreakConstructorInitializers: BeforeComma 87 | 88 | # 总是在template声明后换行 89 | AlwaysBreakTemplateDeclarations: true 90 | 91 | # 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变 92 | CommentPragmas: '^ IWYU pragma:' 93 | 94 | # 固定命名空间注释 95 | FixNamespaceComments: true 96 | 97 | # 对齐连续的尾随的注释 98 | AlignTrailingComments: true 99 | 100 | # 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All 101 | AllowShortFunctionsOnASingleLine: Empty 102 | 103 | # false表示函数实参要么都在同一行,要么都各自一行 104 | BinPackArguments: false 105 | 106 | # false表示所有形参要么都在同一行,要么都各自一行 107 | BinPackParameters: false 108 | 109 | # 需要被解读为foreach循环而不是函数调用的宏 110 | ForEachMacros: 111 | - foreach 112 | - Q_FOREACH 113 | - BOOST_FOREACH 114 | 115 | IndentCaseLabels: true 116 | 117 | IncludeBlocks: Preserve 118 | # 对#include进行排序,匹配了某正则表达式的#include拥有对应的优先级,匹配不到的则默认优先级为INT_MAX(优先级越小排序越靠前), 119 | # 可以定义负数优先级从而保证某些#include永远在最前面 120 | IncludeCategories: 121 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 122 | Priority: 2 123 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 124 | Priority: 3 125 | - Regex: 'stdafx\.' 126 | Priority: 1 127 | - Regex: '.*' 128 | Priority: 1 129 | ... 130 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Android 2 | on: 3 | push: 4 | paths-ignore: 5 | - 'README.md' 6 | - 'LICENSE' 7 | pull_request: 8 | paths-ignore: 9 | - 'README.md' 10 | - 'LICENSE' 11 | jobs: 12 | build: 13 | name: Build 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | matrix: 17 | os: [ubuntu-20.04] 18 | qt_ver: [5.12.10] 19 | qt_target: [android] 20 | qt_arch: [android_x86,android_armv7,android_arm64_v8a] 21 | steps: 22 | - name: Install Qt 23 | uses: jurplel/install-qt-action@v2.10.0 24 | with: 25 | # Version of Qt to install 26 | version: ${{ matrix.qt_ver }} 27 | # Target platform for build 28 | target: ${{ matrix.qt_target }} 29 | # Architecture for Windows/Android 30 | arch: ${{ matrix.qt_arch }} 31 | - uses: actions/checkout@v1 32 | with: 33 | fetch-depth: 1 34 | - name: build android 35 | run: | 36 | export ANDROID_SDK_ROOT=$ANDROID_HOME 37 | export ANDROID_NDK_ROOT=$ANDROID_HOME/ndk-bundle 38 | qmake 39 | make -------------------------------------------------------------------------------- /.github/workflows/ios.yml: -------------------------------------------------------------------------------- 1 | name: IOS 2 | on: 3 | push: 4 | paths-ignore: 5 | - 'README.md' 6 | pull_request: 7 | paths-ignore: 8 | - 'README.md' 9 | jobs: 10 | build: 11 | name: Build 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | matrix: 15 | os: [macos-10.15] 16 | qt_ver: [5.12.10,5.15.2] 17 | qt_target: [ios] 18 | steps: 19 | - name: Install Qt 20 | # if: steps.cacheqt.outputs.cache-hit != 'true' 21 | uses: jurplel/install-qt-action@v2.10.0 22 | with: 23 | # Version of Qt to install 24 | version: ${{ matrix.qt_ver }} 25 | # Target platform for build 26 | target: ${{ matrix.qt_target }} 27 | - uses: actions/checkout@v1 28 | with: 29 | fetch-depth: 1 30 | - name: build ios 31 | run: | 32 | qmake -r -spec macx-ios-clang CONFIG+=release CONFIG+=iphoneos 33 | make 34 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: MacOS 2 | on: 3 | push: 4 | paths-ignore: 5 | - 'README.md' 6 | - 'LICENSE' 7 | pull_request: 8 | paths-ignore: 9 | - 'README.md' 10 | - 'LICENSE' 11 | jobs: 12 | build: 13 | name: Build 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | matrix: 17 | os: [macos-10.15] 18 | qt_ver: [5.9.9,5.12.10,5.15.2] 19 | qt_arch: [clang_64] 20 | env: 21 | targetName: TaoQuickApp 22 | steps: 23 | - name: Install Qt 24 | uses: jurplel/install-qt-action@v2.10.0 25 | with: 26 | version: ${{ matrix.qt_ver }} 27 | cached: 'false' 28 | - uses: actions/checkout@v1 29 | with: 30 | fetch-depth: 1 31 | # submodules: 'true' 32 | - name: build macos 33 | run: | 34 | qmake 35 | make -------------------------------------------------------------------------------- /.github/workflows/ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: Ubuntu 2 | # Qt官方没有linux平台的x86包 3 | on: 4 | push: 5 | paths-ignore: 6 | - 'README.md' 7 | - 'LICENSE' 8 | pull_request: 9 | paths-ignore: 10 | - 'README.md' 11 | - 'LICENSE' 12 | jobs: 13 | build: 14 | name: Build 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | matrix: 18 | os: [ubuntu-18.04,ubuntu-20.04] 19 | qt_ver: [5.9.9,5.12.10,5.15.2] 20 | qt_arch: [gcc_64] 21 | steps: 22 | - name: Install Qt 23 | uses: jurplel/install-qt-action@v2.10.0 24 | with: 25 | version: ${{ matrix.qt_ver }} 26 | cached: 'false' 27 | - name: ubuntu install GL library 28 | run: sudo apt-get install -y libglew-dev libglfw3-dev 29 | - uses: actions/checkout@v1 30 | with: 31 | fetch-depth: 1 32 | # submodules: 'true' 33 | - name: build ubuntu 34 | run: | 35 | qmake 36 | make -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | on: 3 | # push代码时触发workflow 4 | push: 5 | # 忽略README.md 6 | paths-ignore: 7 | - 'README.md' 8 | - 'LICENSE' 9 | # pull_request时触发workflow 10 | pull_request: 11 | # 忽略README.md 12 | paths-ignore: 13 | - 'README.md' 14 | - 'LICENSE' 15 | jobs: 16 | build: 17 | name: Build 18 | # 运行平台, windows-latest目前是windows server 2019 19 | runs-on: windows-latest 20 | strategy: 21 | # 矩阵配置 22 | matrix: 23 | include: 24 | # 5.9.9 参考 https://mirrors.cloud.tencent.com/qt/online/qtsdkrepository/windows_x86/desktop/qt5_599/ 25 | - qt_ver: 5.9.9 26 | qt_arch: win32_msvc2015 27 | msvc_arch: x86 28 | qt_arch_install: msvc2015 29 | - qt_ver: 5.9.9 30 | qt_arch: win64_msvc2017_64 31 | msvc_arch: x64 32 | qt_arch_install: msvc2017_64 33 | # 5.12.10 参考 https://mirrors.cloud.tencent.com/qt/online/qtsdkrepository/windows_x86/desktop/qt5_51210/ 34 | - qt_ver: 5.12.10 35 | qt_arch: win32_msvc2017 36 | msvc_arch: x86 37 | qt_arch_install: msvc2017 38 | - qt_ver: 5.12.10 39 | qt_arch: win64_msvc2017_64 40 | msvc_arch: x64 41 | qt_arch_install: msvc2017_64 42 | # 5.15.2 参考 https://mirrors.cloud.tencent.com/qt/online/qtsdkrepository/windows_x86/desktop/qt5_5152/ 43 | - qt_ver: 5.15.2 44 | qt_arch: win32_msvc2019 45 | msvc_arch: x86 46 | qt_arch_install: msvc2019 47 | - qt_ver: 5.15.2 48 | qt_arch: win64_msvc2019_64 49 | msvc_arch: x64 50 | qt_arch_install: msvc2019_64 51 | # 步骤 52 | steps: 53 | # 安装Qt 54 | - name: Install Qt 55 | # 使用外部action。这个action专门用来安装Qt 56 | uses: jurplel/install-qt-action@v2.10.0 57 | with: 58 | # Version of Qt to install 59 | version: ${{ matrix.qt_ver }} 60 | # Target platform for build 61 | # target: ${{ matrix.qt_target }} 62 | arch: ${{ matrix.qt_arch }} 63 | aqtversion: '==0.10.0' 64 | cached: 'false' 65 | # 拉取代码 66 | - uses: actions/checkout@v1 67 | with: 68 | fetch-depth: 1 69 | # msvc编译 70 | - name: msvc-build 71 | id: build 72 | shell: cmd 73 | run: | 74 | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.msvc_arch }} 75 | qmake 76 | nmake -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | .qmake.cache 3 | .qmake.super 4 | *.user 5 | *.suo 6 | bin 7 | *.qmlc 8 | *temp 9 | *.VC.* 10 | *.stash 11 | *.cbt 12 | debug 13 | *.ipch 14 | *qmlcache.qrc 15 | build 16 | bin 17 | .vc 18 | .vscode 19 | .vs -------------------------------------------------------------------------------- /Common/Common.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD 2 | 3 | 4 | HEADERS += \ 5 | $$PWD/GLCommon.h \ 6 | $$PWD/GLWindow.h 7 | 8 | SOURCES += \ 9 | $$PWD/GLCommon.cpp \ 10 | $$PWD/GLWindow.cpp 11 | -------------------------------------------------------------------------------- /Common/GLCommon.cpp: -------------------------------------------------------------------------------- 1 | #include "GLCommon.h" 2 | #include 3 | #include 4 | void GLCommon::prepareGL() 5 | { 6 | #ifdef Q_OS_ANDROID 7 | auto fmt = QSurfaceFormat::defaultFormat(); 8 | fmt.setMajorVersion(3); 9 | fmt.setMinorVersion(0); 10 | fmt.setProfile(QSurfaceFormat::CoreProfile); 11 | fmt.setRenderableType(QSurfaceFormat::OpenGLES); 12 | #ifdef GL_DEBUG 13 | fmt.setOption(QSurfaceFormat::DebugContext); 14 | #endif 15 | fmt.setDepthBufferSize(24); 16 | QSurfaceFormat::setDefaultFormat(fmt); 17 | #else 18 | auto fmt = QSurfaceFormat::defaultFormat(); 19 | fmt.setMajorVersion(3); 20 | fmt.setMinorVersion(3); 21 | fmt.setProfile(QSurfaceFormat::CoreProfile); 22 | #ifdef GL_DEBUG 23 | fmt.setOption(QSurfaceFormat::DebugContext); 24 | #endif 25 | fmt.setDepthBufferSize(24); 26 | QSurfaceFormat::setDefaultFormat(fmt); 27 | #endif 28 | } 29 | 30 | void GLCommon::prepareApp() 31 | { 32 | QCoreApplication::setOrganizationName("jaredtao"); 33 | QCoreApplication::setOrganizationDomain("jaredtao.github.io"); 34 | 35 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 36 | QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 37 | } 38 | -------------------------------------------------------------------------------- /Common/GLCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class GLCommon 4 | { 5 | public: 6 | //准备GL环境。人为约定GL版本号,Desktop环境使用3.3 core, Android使用 ES 3.0 7 | static void prepareGL(); 8 | //准备App环境。 9 | static void prepareApp(); 10 | }; 11 | -------------------------------------------------------------------------------- /Common/GLWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "GLWindow.h" 2 | #include 3 | #include 4 | GLWindow::GLWindow(QOpenGLWindow::UpdateBehavior updateBehavior, QWindow* parent) 5 | : QOpenGLWindow(updateBehavior, parent) 6 | #ifdef GL_DEBUG 7 | , mDebugger(this) 8 | #endif 9 | { 10 | resize(1280, 760); 11 | startTimer(QSurfaceFormat::defaultFormat().swapInterval()); 12 | } 13 | 14 | GLWindow::GLWindow(QOpenGLContext* shareContext, QOpenGLWindow::UpdateBehavior updateBehavior, QWindow* parent) 15 | : QOpenGLWindow(shareContext, updateBehavior, parent) 16 | #ifdef GL_DEBUG 17 | , mDebugger(this) 18 | #endif 19 | { 20 | resize(1280, 760); 21 | startTimer(QSurfaceFormat::defaultFormat().swapInterval()); 22 | } 23 | 24 | GLWindow::~GLWindow() 25 | { 26 | makeCurrent(); 27 | #ifdef GL_DEBUG 28 | if (mDebugger.isLogging()) 29 | { 30 | mDebugger.stopLogging(); 31 | } 32 | #endif 33 | doneCurrent(); 34 | } 35 | 36 | void GLWindow::initializeGL() 37 | { 38 | initializeOpenGLFunctions(); 39 | #ifdef GL_DEBUG 40 | mDebugger.initialize(); 41 | connect(&mDebugger, &QOpenGLDebugLogger::messageLogged, this, &GLWindow::onDebuggerMessage); 42 | mDebugger.startLogging(); 43 | #endif 44 | mElapsed.start(); 45 | mFrame = 0; 46 | } 47 | 48 | void GLWindow::resizeGL(int w, int h) 49 | { 50 | resize(w, h); 51 | glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 52 | } 53 | 54 | void GLWindow::paintGL() 55 | { 56 | calcFPS(); 57 | } 58 | 59 | void GLWindow::calcFPS() 60 | { 61 | mFrame++; 62 | if (mFrame > 100) 63 | { 64 | auto cost = mElapsed.elapsed(); 65 | updateFPS(1.0 * mFrame / cost * 1000); 66 | mFrame = 0; 67 | mElapsed.restart(); 68 | } 69 | } 70 | void GLWindow::updateFPS(qreal v) 71 | { 72 | mFps = v; 73 | } 74 | 75 | void GLWindow::timerEvent(QTimerEvent*) 76 | { 77 | update(); 78 | } 79 | #ifdef GL_DEBUG 80 | void GLWindow::onDebuggerMessage(const QOpenGLDebugMessage& debugMessage) 81 | { 82 | qWarning() << debugMessage.message(); 83 | } 84 | #endif 85 | -------------------------------------------------------------------------------- /Common/GLWindow.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #ifdef GL_DEBUG 4 | #include 5 | #endif 6 | #include 7 | #include 8 | class GLWindow 9 | : public QOpenGLWindow 10 | , public QOpenGLExtraFunctions 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit GLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow* parent = nullptr); 15 | explicit GLWindow(QOpenGLContext* shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow* parent = nullptr); 16 | virtual ~GLWindow(); 17 | 18 | protected: 19 | virtual void initializeGL() override; 20 | virtual void resizeGL(int w, int h) override; 21 | virtual void paintGL() override; 22 | 23 | void timerEvent(QTimerEvent*) override; 24 | protected slots: 25 | #ifdef GL_DEBUG 26 | void onDebuggerMessage(const QOpenGLDebugMessage& debugMessage); 27 | #endif 28 | protected: 29 | void calcFPS(); 30 | void updateFPS(qreal v); 31 | 32 | protected: 33 | #ifdef GL_DEBUG 34 | QOpenGLDebugLogger mDebugger; 35 | #endif 36 | qreal mFps = 60.0; 37 | QElapsedTimer mElapsed; 38 | int mFrame = 0; 39 | }; 40 | -------------------------------------------------------------------------------- /DepthTest/DepthTest.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-09-22T10:04:40 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui widgets 8 | 9 | CONFIG += c+=11 10 | TEMPLATE = app 11 | 12 | HEADERS += \ 13 | src/cube.h \ 14 | src/window.h \ 15 | src/floor.h 16 | 17 | SOURCES += \ 18 | src/cube.cpp \ 19 | src/main.cpp \ 20 | src/window.cpp \ 21 | src/floor.cpp 22 | 23 | RESOURCES += \ 24 | res/shader.qrc \ 25 | res/texture.qrc 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /DepthTest/res/image/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/DepthTest/res/image/cube.png -------------------------------------------------------------------------------- /DepthTest/res/image/cube1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/DepthTest/res/image/cube1.png -------------------------------------------------------------------------------- /DepthTest/res/image/w1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/DepthTest/res/image/w1.png -------------------------------------------------------------------------------- /DepthTest/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fshader.glsl 4 | shader/vshader.glsl 5 | shader/singleColor.glsl 6 | 7 | 8 | -------------------------------------------------------------------------------- /DepthTest/res/shader/fshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D texture; 8 | 9 | varying vec2 v_texcoord; 10 | 11 | //! [0] 12 | void main() 13 | { 14 | // Set fragment color from texture 15 | gl_FragColor = texture2D(texture, v_texcoord); 16 | } 17 | //! [0] 18 | 19 | -------------------------------------------------------------------------------- /DepthTest/res/shader/singleColor.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D texture; 8 | 9 | varying vec2 v_texcoord; 10 | 11 | //! [0] 12 | void main() 13 | { 14 | // Set fragment color from texture 15 | gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 16 | } 17 | //! [0] 18 | 19 | 20 | -------------------------------------------------------------------------------- /DepthTest/res/shader/vshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | uniform mat4 mvp_matrix; 8 | 9 | attribute vec4 a_position; 10 | attribute vec2 a_texcoord; 11 | 12 | varying vec2 v_texcoord; 13 | 14 | //! [0] 15 | void main() 16 | { 17 | // Calculate vertex position in screen space 18 | gl_Position = mvp_matrix * a_position; 19 | 20 | // Pass texture coordinate to fragment shader 21 | // Value will be automatically interpolated to fragments inside polygon faces 22 | v_texcoord = a_texcoord; 23 | } 24 | //! [0] 25 | -------------------------------------------------------------------------------- /DepthTest/res/texture.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/cube.png 4 | image/cube1.png 5 | image/w1.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /DepthTest/src/cube.cpp: -------------------------------------------------------------------------------- 1 | #include "cube.h" 2 | #include 3 | #include 4 | 5 | #define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0])) 6 | struct VertexData 7 | { 8 | QVector3D position; 9 | QVector2D texCoord; 10 | }; 11 | 12 | Cube::Cube() 13 | : indexBuf(QOpenGLBuffer::IndexBuffer) 14 | , texture(nullptr) 15 | { 16 | initializeOpenGLFunctions(); 17 | 18 | // Generate 2 VBOs 19 | arrayBuf.create(); 20 | indexBuf.create(); 21 | 22 | // Initializes cube geometry and transfers it to VBOs 23 | initCube(); 24 | } 25 | Cube::~Cube() 26 | { 27 | arrayBuf.destroy(); 28 | indexBuf.destroy(); 29 | if (texture) 30 | { 31 | delete texture; 32 | texture = nullptr; 33 | } 34 | } 35 | 36 | void Cube::initVertex() 37 | { 38 | // For cube we would need only 8 vertices but we have to 39 | // duplicate vertex for each face because texture coordinate 40 | // is different. 41 | VertexData vertices[] = { 42 | // Vertex data for face 0 43 | { QVector3D(-0.5f, -0.5f, 0.5f), QVector2D(0.0f, 0.0f) }, // v0 44 | { QVector3D(0.5f, -0.5f, 0.5f), QVector2D(0.33f, 0.0f) }, // v1 45 | { QVector3D(-0.5f, 0.5f, 0.5f), QVector2D(0.0f, 0.5f) }, // v2 46 | { QVector3D(0.5f, 0.5f, 0.5f), QVector2D(0.33f, 0.5f) }, // v3 47 | 48 | // Vertex data for face 1 49 | { QVector3D(0.5f, -0.5f, 0.5f), QVector2D(0.0f, 0.5f) }, // v4 50 | { QVector3D(0.5f, -0.5f, -0.5f), QVector2D(0.33f, 0.5f) }, // v5 51 | { QVector3D(0.5f, 0.5f, 0.5f), QVector2D(0.0f, 1.0f) }, // v6 52 | { QVector3D(0.5f, 0.5f, -0.5f), QVector2D(0.33f, 1.0f) }, // v7 53 | 54 | // Vertex data for face 2 55 | { QVector3D(0.5f, -0.5f, -0.5f), QVector2D(0.66f, 0.5f) }, // v8 56 | { QVector3D(-0.5f, -0.5f, -0.5f), QVector2D(1.0f, 0.5f) }, // v9 57 | { QVector3D(0.5f, 0.5f, -0.5f), QVector2D(0.66f, 1.0f) }, // v10 58 | { QVector3D(-0.5f, 0.5f, -0.5f), QVector2D(1.0f, 1.0f) }, // v11 59 | 60 | // Vertex data for face 3 61 | { QVector3D(-0.5f, -0.5f, -0.5f), QVector2D(0.66f, 0.0f) }, // v12 62 | { QVector3D(-0.5f, -0.5f, 0.5f), QVector2D(1.0f, 0.0f) }, // v13 63 | { QVector3D(-0.5f, 0.5f, -0.5f), QVector2D(0.66f, 0.5f) }, // v14 64 | { QVector3D(-0.5f, 0.5f, 0.5f), QVector2D(1.0f, 0.5f) }, // v15 65 | 66 | // Vertex data for face 4 67 | { QVector3D(-0.5f, -0.5f, -0.5f), QVector2D(0.33f, 0.0f) }, // v16 68 | { QVector3D(0.5f, -0.5f, -0.5f), QVector2D(0.66f, 0.0f) }, // v17 69 | { QVector3D(-0.5f, -0.5f, 0.5f), QVector2D(0.33f, 0.5f) }, // v18 70 | { QVector3D(0.5f, -0.5f, 0.5f), QVector2D(0.66f, 0.5f) }, // v19 71 | 72 | // Vertex data for face 5 73 | { QVector3D(-0.5f, 0.5f, 0.5f), QVector2D(0.33f, 0.5f) }, // v20 74 | { QVector3D(0.5f, 0.5f, 0.5f), QVector2D(0.66f, 0.5f) }, // v21 75 | { QVector3D(-0.5f, 0.5f, -0.5f), QVector2D(0.33f, 1.0f) }, // v22 76 | { QVector3D(0.5f, 0.5f, -0.5f), QVector2D(0.66f, 1.0f) } // v23 77 | }; 78 | 79 | // Indices for drawing cube faces using triangle strips. 80 | // Triangle strips can be connected by duplicating indices 81 | // between the strips. If connecting strips have opposite 82 | // vertex order then last index of the first strip and first 83 | // index of the second strip needs to be duplicated. If 84 | // connecting strips have same vertex order then only last 85 | // index of the first strip needs to be duplicated. 86 | GLushort indices[] = { 87 | 0, 1, 2, 3, 3, // Face 0 - triangle strip ( v0, v1, v2, v3) 88 | 4, 4, 5, 6, 7, 7, // Face 1 - triangle strip ( v4, v5, v6, v7) 89 | 8, 8, 9, 10, 11, 11, // Face 2 - triangle strip ( v8, v9, v10, v11) 90 | 12, 12, 13, 14, 15, 15, // Face 3 - triangle strip (v12, v13, v14, v15) 91 | 16, 16, 17, 18, 19, 19, // Face 4 - triangle strip (v16, v17, v18, v19) 92 | 20, 20, 21, 22, 23 // Face 5 - triangle strip (v20, v21, v22, v23) 93 | }; 94 | 95 | //! [1] 96 | // Transfer vertex data to VBO 0 97 | arrayBuf.bind(); 98 | arrayBuf.allocate(vertices, sizeof(vertices)); 99 | 100 | // Transfer index data to VBO 1 101 | indexBuf.bind(); 102 | indexBuf.allocate(indices, sizeof(indices)); 103 | } 104 | 105 | void Cube::initTexture() 106 | { 107 | texture = new QOpenGLTexture(QImage(":/image/cube.png").mirrored()); 108 | texture->setMinificationFilter(QOpenGLTexture::Nearest); 109 | texture->setMagnificationFilter(QOpenGLTexture::Linear); 110 | texture->setWrapMode(QOpenGLTexture::Repeat); 111 | } 112 | 113 | void Cube::initCube() 114 | { 115 | initVertex(); 116 | initTexture(); 117 | } 118 | void Cube::drawCube(QOpenGLShaderProgram* program) 119 | { 120 | // Tell OpenGL which VBOs to use 121 | arrayBuf.bind(); 122 | indexBuf.bind(); 123 | 124 | // Offset for position 125 | quintptr offset = 0; 126 | 127 | // Tell OpenGL programmable pipeline how to locate vertex position data 128 | int vertexLocation = program->attributeLocation("a_position"); 129 | program->enableAttributeArray(vertexLocation); 130 | program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(VertexData)); 131 | 132 | // Offset for texture coordinate 133 | offset += sizeof(QVector3D); 134 | 135 | // Tell OpenGL programmable pipeline how to locate vertex texture coordinate data 136 | int texcoordLocation = program->attributeLocation("a_texcoord"); 137 | program->enableAttributeArray(texcoordLocation); 138 | program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(VertexData)); 139 | 140 | texture->bind(); 141 | program->setUniformValue("texture", 0); 142 | 143 | // Draw cube geometry using indices from VBO 1 144 | glDrawElements(GL_TRIANGLE_STRIP, 34, GL_UNSIGNED_SHORT, 0); 145 | } 146 | -------------------------------------------------------------------------------- /DepthTest/src/cube.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_H 2 | #define CUBE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | class Cube : protected QOpenGLFunctions 9 | { 10 | public: 11 | Cube(); 12 | virtual ~Cube(); 13 | void drawCube(QOpenGLShaderProgram* program); 14 | 15 | private: 16 | void initCube(); 17 | 18 | void initTexture(); 19 | void initVertex(); 20 | QOpenGLBuffer arrayBuf; 21 | QOpenGLBuffer indexBuf; 22 | QOpenGLTexture* texture; 23 | }; 24 | 25 | #endif // CUBE_H 26 | -------------------------------------------------------------------------------- /DepthTest/src/floor.cpp: -------------------------------------------------------------------------------- 1 | #include "floor.h" 2 | #include 3 | #include 4 | 5 | #define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0])) 6 | struct VertexData 7 | { 8 | QVector3D position; 9 | QVector2D texCoord; 10 | }; 11 | 12 | Floor::Floor() 13 | : arrayBuffer(QOpenGLBuffer::VertexBuffer) 14 | , texture(0) 15 | { 16 | initializeOpenGLFunctions(); 17 | arrayBuffer.create(); 18 | init(); 19 | } 20 | 21 | Floor::~Floor() 22 | { 23 | arrayBuffer.destroy(); 24 | if (texture) 25 | { 26 | delete texture; 27 | texture = nullptr; 28 | } 29 | } 30 | 31 | void Floor::init() 32 | { 33 | VertexData vertices[] = { 34 | { QVector3D(5.0f, -0.5f, 5.0f), QVector2D(2.0f, 0.0f) }, { QVector3D(-5.0f, -0.5f, 5.0f), QVector2D(0.0f, 0.0f) }, 35 | { QVector3D(-5.0f, -0.5f, -5.0f), QVector2D(0.0f, 2.0f) }, 36 | 37 | { QVector3D(5.0f, -0.5f, 5.0f), QVector2D(2.0f, 0.0f) }, { QVector3D(-5.0f, -0.5f, -5.0f), QVector2D(0.0f, 2.0f) }, 38 | { QVector3D(5.0f, -0.5f, -5.0f), QVector2D(2.0f, 2.0f) }, 39 | }; 40 | arrayBuffer.bind(); 41 | arrayBuffer.allocate(vertices, sizeof(vertices)); 42 | 43 | texture = new QOpenGLTexture(QImage(":/image/w1.png").mirrored()); 44 | texture->setMinificationFilter(QOpenGLTexture::Nearest); 45 | texture->setMagnificationFilter(QOpenGLTexture::Linear); 46 | texture->setWrapMode(QOpenGLTexture::Repeat); 47 | } 48 | void Floor::Draw(QOpenGLShaderProgram* program) 49 | { 50 | arrayBuffer.bind(); 51 | int vertexHandle = program->attributeLocation("a_position"); 52 | program->enableAttributeArray(vertexHandle); 53 | program->setAttributeBuffer(vertexHandle, GL_FLOAT, 0, 3, sizeof(VertexData)); 54 | 55 | int texcoordHandle = program->attributeLocation("a_texcoord"); 56 | program->enableAttributeArray(texcoordHandle); 57 | program->setAttributeBuffer(texcoordHandle, GL_FLOAT, offsetof(VertexData, texCoord), 2, sizeof(VertexData)); 58 | 59 | texture->bind(); 60 | program->setUniformValue("texture", 0); 61 | 62 | glDrawArrays(GL_TRIANGLE_STRIP, 0, arrayBuffer.size()); 63 | } 64 | -------------------------------------------------------------------------------- /DepthTest/src/floor.h: -------------------------------------------------------------------------------- 1 | #ifndef FLOOR_H 2 | #define FLOOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | class Floor : protected QOpenGLFunctions 9 | { 10 | public: 11 | Floor(); 12 | ~Floor(); 13 | void Draw(QOpenGLShaderProgram* program); 14 | 15 | protected: 16 | void init(); 17 | QOpenGLBuffer arrayBuffer; 18 | QOpenGLTexture* texture; 19 | }; 20 | 21 | #endif // FLOOR_H 22 | -------------------------------------------------------------------------------- /DepthTest/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef QT_NO_OPENGL 6 | #include "window.h" 7 | #endif 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | QApplication app(argc, argv); 12 | 13 | QSurfaceFormat format; 14 | format.setDepthBufferSize(24); 15 | QSurfaceFormat::setDefaultFormat(format); 16 | 17 | app.setApplicationName("cube"); 18 | app.setApplicationVersion("0.1"); 19 | #ifndef QT_NO_OPENGL 20 | Window win; 21 | win.show(); 22 | #else 23 | QLabel note("OpenGL Support required"); 24 | note.show(); 25 | #endif 26 | return app.exec(); 27 | } 28 | -------------------------------------------------------------------------------- /DepthTest/src/window.cpp: -------------------------------------------------------------------------------- 1 | #include "window.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "cube.h" 9 | #include "floor.h" 10 | Window::Window(QWidget* parent) 11 | : QOpenGLWidget(parent) 12 | , cube(0) 13 | , floor(0) 14 | , angularSpeed(0) 15 | { 16 | fps = 60.0; 17 | } 18 | Window::~Window() 19 | { 20 | makeCurrent(); 21 | delete cube; 22 | delete floor; 23 | doneCurrent(); 24 | } 25 | void Window::mousePressEvent(QMouseEvent* e) 26 | { 27 | // Save mouse press position 28 | mousePressPosition = QVector2D(e->localPos()); 29 | } 30 | void Window::mouseReleaseEvent(QMouseEvent* e) 31 | { 32 | // Mouse release position - mouse press position 33 | QVector2D diff = QVector2D(e->localPos()) - mousePressPosition; 34 | 35 | // Rotation axis is perpendicular to the mouse position difference 36 | // vector 37 | QVector3D n = QVector3D(diff.y(), diff.x(), 0.0).normalized(); 38 | 39 | // Accelerate angular speed relative to the length of the mouse sweep 40 | qreal acc = diff.length() / 100.0; 41 | 42 | // Calculate new rotation axis as weighted sum 43 | rotationAxis = (rotationAxis * angularSpeed + n * acc).normalized(); 44 | 45 | // Increase angular speed 46 | angularSpeed += acc; 47 | } 48 | void Window::timerEvent(QTimerEvent*) 49 | { 50 | // Decrease angular speed (friction) 51 | angularSpeed *= 0.99; 52 | 53 | // Stop rotation when speed goes below threshold 54 | if (angularSpeed < 0.01) 55 | { 56 | angularSpeed = 0.0; 57 | } 58 | else 59 | { 60 | // Update rotation 61 | rotation = QQuaternion::fromAxisAndAngle(rotationAxis, angularSpeed) * rotation; 62 | // Request an update 63 | update(); 64 | } 65 | } 66 | void Window::initializeGL() 67 | { 68 | initializeOpenGLFunctions(); 69 | 70 | glClearColor(0, 0, 0, 1); 71 | initShaders(); 72 | 73 | glEnable(GL_DEPTH_TEST); 74 | glDepthFunc(GL_LESS); 75 | glEnable(GL_CULL_FACE); 76 | 77 | glEnable(GL_STENCIL_TEST); 78 | glStencilFunc(GL_NOTEQUAL, 1, 0xFF); 79 | glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 80 | 81 | cube = new Cube; 82 | floor = new Floor; 83 | 84 | startTimer(12); 85 | } 86 | void Window::initShaders() 87 | { 88 | program.removeAllShaders(); 89 | if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vshader.glsl")) 90 | { 91 | qDebug() << __FILE__ << __FUNCTION__ << " add vertex shader file failed."; 92 | close(); 93 | } 94 | if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fshader.glsl")) 95 | { 96 | qDebug() << __FILE__ << __FUNCTION__ << " add fragment shader file failed."; 97 | close(); 98 | } 99 | 100 | if (!program.link()) 101 | { 102 | qDebug() << __FILE__ << __LINE__ << "program link failed"; 103 | close(); 104 | } 105 | if (!program.bind()) 106 | { 107 | qDebug() << __FILE__ << __LINE__ << "program bind failed"; 108 | close(); 109 | } 110 | } 111 | 112 | void Window::useSiangleColorShader() 113 | { 114 | program.removeAllShaders(); 115 | if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vshader.glsl")) 116 | { 117 | qDebug() << __FILE__ << __FUNCTION__ << " add vertex shader file failed."; 118 | close(); 119 | } 120 | if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/singleColor.glsl")) 121 | { 122 | qDebug() << __FILE__ << __FUNCTION__ << " add fragment shader file failed."; 123 | close(); 124 | } 125 | 126 | if (!program.link()) 127 | { 128 | qDebug() << __FILE__ << __LINE__ << "program link failed"; 129 | close(); 130 | } 131 | if (!program.bind()) 132 | { 133 | qDebug() << __FILE__ << __LINE__ << "program bind failed"; 134 | close(); 135 | } 136 | } 137 | 138 | void Window::resizeGL(int w, int h) 139 | { 140 | // Calculate aspect ratio 141 | qreal aspect = qreal(w) / qreal(h ? h : 1); 142 | 143 | // Set near plane to 3.0, far plane to 7.0, field of view 45 degrees 144 | const qreal zNear = 0.1f, zFar = 100.0, fov = 45.0; 145 | 146 | // Reset projection 147 | projection.setToIdentity(); 148 | // Set perspective projection 149 | projection.perspective(fov, aspect, zNear, zFar); 150 | } 151 | 152 | void Window::paintGL() 153 | { 154 | initShaders(); 155 | glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 156 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 157 | 158 | QMatrix4x4 matrix, view; 159 | 160 | view.setToIdentity(); 161 | view.lookAt(QVector3D(0.0f, 0.5f, 3.0f), QVector3D(0.0f, 0.0f, -1.0f), QVector3D(0.0f, 1.0f, 0.0f)); 162 | view.rotate(QQuaternion::fromAxisAndAngle(1.0, 0, 0, 45)); 163 | 164 | program.setUniformValue("mvp_matrix", projection * view); 165 | glStencilMask(0x00); 166 | floor->Draw(&program); 167 | 168 | { 169 | // 1st. Render pass, draw objects as normal, filling the stencil buffer 170 | glStencilFunc(GL_ALWAYS, 1, 0xFF); 171 | glStencilMask(0xFF); 172 | 173 | matrix.setToIdentity(); 174 | matrix.translate(-0.5f, 0.0, -1.5f); 175 | matrix.rotate(rotation); 176 | 177 | program.setUniformValue("mvp_matrix", projection * view * matrix); 178 | cube->drawCube(&program); 179 | 180 | matrix.setToIdentity(); 181 | matrix.translate(0.3f, 0.0f, 0.0f); 182 | // matrix.rotate(rotation); 183 | program.setUniformValue("mvp_matrix", projection * view * matrix); 184 | cube->drawCube(&program); 185 | } 186 | { 187 | // 2nd. Render pass, now draw slightly scaled versions of the objects, this time disabling stencil writing. 188 | // Because stencil buffer is now filled with several 1s. The parts of the buffer that are 1 are now not drawn, thus only drawing 189 | // the objects' size differences, making it look like borders. 190 | glStencilFunc(GL_NOTEQUAL, 1, 0xFF); 191 | glStencilMask(0x00); 192 | glDisable(GL_DEPTH_TEST); 193 | useSiangleColorShader(); 194 | 195 | matrix.setToIdentity(); 196 | matrix.translate(-0.5f, 0.0, -1.5f); 197 | matrix.rotate(rotation); 198 | matrix.scale(1.04); 199 | program.setUniformValue("mvp_matrix", projection * view * matrix); 200 | cube->drawCube(&program); 201 | 202 | matrix.setToIdentity(); 203 | matrix.translate(0.3f, 0.0f, 0.0f); 204 | // matrix.rotate(rotation); 205 | program.setUniformValue("mvp_matrix", projection * view * matrix); 206 | cube->drawCube(&program); 207 | glStencilMask(0xFF); 208 | glEnable(GL_DEPTH_TEST); 209 | } 210 | 211 | calcFPS(); 212 | paintFPS(); 213 | } 214 | 215 | void Window::calcFPS() 216 | { 217 | static QTime time; 218 | static int once = [=]() { 219 | time.start(); 220 | return 0; 221 | }(); 222 | Q_UNUSED(once) 223 | static int frame = 0; 224 | if (frame++ > 100) 225 | { 226 | qreal elasped = time.elapsed(); 227 | updateFPS(frame / elasped * 1000); 228 | time.restart(); 229 | frame = 0; 230 | } 231 | } 232 | void Window::updateFPS(qreal v) 233 | { 234 | fps = v; 235 | } 236 | void Window::paintFPS() 237 | { 238 | QString str = QString("FPS:%1").arg(QString::number(fps, 'f', 3)); 239 | this->setWindowTitle(str); 240 | } 241 | -------------------------------------------------------------------------------- /DepthTest/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class Cube; 13 | class Floor; 14 | class Window 15 | : public QOpenGLWidget 16 | , protected QOpenGLFunctions 17 | { 18 | Q_OBJECT 19 | public: 20 | explicit Window(QWidget* parent = 0); 21 | ~Window(); 22 | 23 | protected: 24 | void mousePressEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 25 | void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 26 | void timerEvent(QTimerEvent* e) Q_DECL_OVERRIDE; 27 | 28 | void initializeGL() Q_DECL_OVERRIDE; 29 | void paintGL() Q_DECL_OVERRIDE; 30 | void resizeGL(int w, int h) Q_DECL_OVERRIDE; 31 | 32 | void initShaders(); 33 | 34 | private: 35 | void useSiangleColorShader(); 36 | void calcFPS(); 37 | void updateFPS(qreal); 38 | void paintFPS(); 39 | 40 | private: 41 | QBasicTimer timer; 42 | QOpenGLShaderProgram program; 43 | Cube* cube; 44 | Floor* floor; 45 | QMatrix4x4 projection; 46 | 47 | QVector2D mousePressPosition; 48 | QVector3D rotationAxis; 49 | qreal angularSpeed; 50 | QQuaternion rotation; 51 | qreal fps; 52 | 53 | GLuint fbo; 54 | }; 55 | 56 | #endif // WINDOW_H 57 | -------------------------------------------------------------------------------- /FrameBufferObject/FrameBufferObject.pro: -------------------------------------------------------------------------------- 1 | QT += core gui qml quick widgets 2 | 3 | CONFIG += c++11 4 | 5 | # Additional import path used to resolve QML modules in Qt Creator's code model 6 | QML_IMPORT_PATH = 7 | 8 | RESOURCES += \ 9 | res/img.qrc \ 10 | res/qml.qrc \ 11 | res/shader.qrc 12 | 13 | HEADERS += \ 14 | src/item.h \ 15 | src/easy.h \ 16 | src/render.h 17 | 18 | SOURCES += \ 19 | src/main.cpp \ 20 | src/item.cpp \ 21 | src/render.cpp 22 | -------------------------------------------------------------------------------- /FrameBufferObject/res/img.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | img/s.jpg 4 | 5 | 6 | -------------------------------------------------------------------------------- /FrameBufferObject/res/img/s.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/FrameBufferObject/res/img/s.jpg -------------------------------------------------------------------------------- /FrameBufferObject/res/qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | qml/main.qml 4 | 5 | 6 | -------------------------------------------------------------------------------- /FrameBufferObject/res/qml/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.5 2 | import QtQuick.Controls 1.4 as QQ1 3 | import QtQuick.Controls 2.0 4 | import QtQuick.Layouts 1.0 5 | import TaoItem 1.0 6 | import QtQuick.Window 2.2 7 | 8 | Item { 9 | id:root 10 | width: Screen.width / 2 11 | height: Screen.height / 2 12 | TaoItem { 13 | anchors.fill: parent 14 | } 15 | // TaoItem { 16 | // id:taoItem 17 | // width: 400 18 | // height:400 19 | // x:(root.width - width) / 2 20 | // y:(root.height - height) / 2 21 | // xRotate:0 22 | // yRotate:0 23 | // zRotate:0 24 | // full:false 25 | // states: [ 26 | // State{ 27 | // name:"TopLeft" 28 | // PropertyChanges {target:taoItem; x:0; y:0;} 29 | // }, 30 | // State{ 31 | // name:"TopRight" 32 | // PropertyChanges {target:taoItem; x:root.width - width; y:0;} 33 | // }, 34 | // State{ 35 | // name:"BottomLeft" 36 | // PropertyChanges {target:taoItem; x:0; y:root.height - height;} 37 | // }, 38 | // State{ 39 | // name:"BottomRight" 40 | // PropertyChanges {target:taoItem; x:root.width - width; y:root.height - height;} 41 | // }, 42 | // State{ 43 | // name:"Middle" 44 | // PropertyChanges {target:taoItem; x:(root.width - width)/2; y:(root.height - height) / 2;} 45 | // } 46 | // ] 47 | // transitions: Transition { 48 | // PropertyAnimation { duration: 750; properties: "x,y"; easing.type: Easing.InOutQuad } 49 | // } 50 | // state:"Middle" 51 | // Text { 52 | // text:taoItem.fps.toFixed(2) 53 | // color:"green" 54 | // font.pixelSize: 12 55 | // anchors.left: parent.left 56 | // anchors.top:parent.top 57 | // } 58 | // } 59 | // Row { 60 | // anchors.top:parent.top; 61 | // anchors.horizontalCenter: parent.horizontalCenter 62 | // spacing: 5 63 | // Button { 64 | // text:"FullScreen" 65 | // onClicked: taoItem.full = !taoItem.full 66 | // } 67 | // Button { 68 | // text:"Quit" 69 | // onClicked: Qt.quit() 70 | // } 71 | // } 72 | // Button { 73 | // text:"TopLeft" 74 | // anchors{top:parent.top; left:parent.left} 75 | // onClicked: taoItem.state = "TopLeft" 76 | // } 77 | // Button { 78 | // text:"TopRight" 79 | // anchors{top:parent.top; right:parent.right} 80 | // onClicked: taoItem.state = "TopRight" 81 | // } 82 | // Button { 83 | // text:"BottomLeft" 84 | // anchors{bottom:parent.bottom; left:parent.left} 85 | // onClicked: taoItem.state = "BottomLeft" 86 | // } 87 | // Button { 88 | // text:"BottomRight" 89 | // anchors{bottom:parent.bottom; right:parent.right} 90 | // onClicked: taoItem.state = "BottomRight" 91 | // } 92 | // Button { 93 | // text:"middle" 94 | // anchors.centerIn: parent 95 | // onClicked: taoItem.state = "Middle" 96 | // } 97 | // Column { 98 | 99 | // anchors{ 100 | // left:parent.left 101 | // verticalCenter: parent.verticalCenter 102 | // } 103 | // Row{ 104 | // Text{ 105 | // text:"X" 106 | // anchors.verticalCenter: parent.verticalCenter 107 | // } 108 | // QQ1.Slider { 109 | // value:0 110 | // minimumValue:0 111 | // maximumValue :360 112 | // onValueChanged: { 113 | // taoItem.xRotate = value; 114 | // } 115 | // } 116 | // } 117 | // Row{ 118 | // Text{ 119 | // text:"Y" 120 | // anchors.verticalCenter: parent.verticalCenter 121 | // } 122 | // QQ1.Slider { 123 | // value:0 124 | // minimumValue:0 125 | // maximumValue :360 126 | // onValueChanged:{ 127 | // taoItem.yRotate = value; 128 | // } 129 | // } 130 | // } 131 | // Row{ 132 | // Text{ 133 | // text:"Z" 134 | // anchors.verticalCenter: parent.verticalCenter 135 | // } 136 | // QQ1.Slider{ 137 | // value:0 138 | // minimumValue:0 139 | // maximumValue :360 140 | // onValueChanged: { 141 | // taoItem.zRotate = value; 142 | // } 143 | // } 144 | // } 145 | // } 146 | } 147 | -------------------------------------------------------------------------------- /FrameBufferObject/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fragment.glsl 4 | shader/vertex.glsl 5 | 6 | 7 | -------------------------------------------------------------------------------- /FrameBufferObject/res/shader/fragment.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | #ifdef GL_ES 4 | // Set default precision to medium 5 | precision mediump int; 6 | precision mediump float; 7 | #endif 8 | 9 | uniform sampler2D qt_Texture0; 10 | in highp vec4 qt_TexCoord0; 11 | in vec4 v_Color; 12 | out vec4 color; 13 | void main(void) 14 | { 15 | color = texture2D(qt_Texture0, qt_TexCoord0.st); 16 | } 17 | -------------------------------------------------------------------------------- /FrameBufferObject/res/shader/vertex.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | #ifdef GL_ES 4 | // Set default precision to medium 5 | precision mediump int; 6 | precision mediump float; 7 | #endif 8 | 9 | layout (location = 0) in vec4 qt_Vertex; 10 | layout (location = 1) in vec4 qt_MultiTexCoord0; 11 | layout (location = 2) in vec4 a_Color; 12 | uniform mat4 qt_ModelViewProjectionMatrix; 13 | out vec4 qt_TexCoord0; 14 | out vec4 v_Color; 15 | void main(void) 16 | { 17 | v_Color = a_Color; 18 | gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; 19 | qt_TexCoord0 = qt_MultiTexCoord0; 20 | } 21 | -------------------------------------------------------------------------------- /FrameBufferObject/src/easy.h: -------------------------------------------------------------------------------- 1 | #ifndef EASY_H 2 | #define EASY_H 3 | #define SafeDeletePtr(ptr) \ 4 | do \ 5 | { \ 6 | if (ptr) \ 7 | { \ 8 | delete ptr; \ 9 | ptr = nullptr; \ 10 | } \ 11 | } while (0); 12 | #define SafeDeleteArray(ptr) \ 13 | do \ 14 | { \ 15 | if (ptr) \ 16 | { \ 17 | delete[] ptr; \ 18 | ptr = nullptr; \ 19 | } \ 20 | } while (0); 21 | #define ArrayLen(array) (int)(sizeof(array) / sizeof(array[0])) 22 | 23 | #endif // EASY_H 24 | -------------------------------------------------------------------------------- /FrameBufferObject/src/item.cpp: -------------------------------------------------------------------------------- 1 | #include "item.h" 2 | #include "render.h" 3 | #include 4 | #include 5 | class ItemRender : public QQuickFramebufferObject::Renderer 6 | { 7 | public: 8 | ItemRender(); 9 | 10 | void render() override; 11 | QOpenGLFramebufferObject* createFramebufferObject(const QSize& size) override; 12 | void synchronize(QQuickFramebufferObject*) override; 13 | Render m_render; 14 | }; 15 | ItemRender::ItemRender() 16 | { 17 | m_render.init(); 18 | } 19 | 20 | void ItemRender::render() 21 | { 22 | m_render.paint(); 23 | } 24 | 25 | void ItemRender::synchronize(QQuickFramebufferObject* item) 26 | { 27 | Item* shader = qobject_cast(item); 28 | m_render.setRotate(shader->xRotate(), shader->yRotate(), shader->zRotate()); 29 | shader->updateFPS(m_render.getFPS()); 30 | } 31 | 32 | QOpenGLFramebufferObject* ItemRender::createFramebufferObject(const QSize& size) 33 | { 34 | QOpenGLFramebufferObjectFormat format; 35 | format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); 36 | format.setSamples(4); 37 | return new QOpenGLFramebufferObject(size, format); 38 | } 39 | 40 | QQuickFramebufferObject::Renderer* Item::createRenderer() const 41 | { 42 | return new ItemRender; 43 | } 44 | -------------------------------------------------------------------------------- /FrameBufferObject/src/item.h: -------------------------------------------------------------------------------- 1 | #ifndef SHADER_H 2 | #define SHADER_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | class Item : public QQuickFramebufferObject 9 | { 10 | Q_OBJECT 11 | Q_PROPERTY(qreal xRotate READ xRotate WRITE setXRotate NOTIFY xRotateChanged) 12 | Q_PROPERTY(qreal yRotate READ yRotate WRITE setYRotate NOTIFY yRotateChanged) 13 | Q_PROPERTY(qreal zRotate READ zRotate WRITE setZRotate NOTIFY zRotateChanged) 14 | Q_PROPERTY(bool full READ full WRITE setFull NOTIFY fullChanged) 15 | Q_PROPERTY(qreal fps READ fps NOTIFY fpsChanged) 16 | 17 | public: 18 | Item(QQuickItem* parent = 0) 19 | : QQuickFramebufferObject(parent) 20 | , m_xRotate(0) 21 | , m_yRotate(0) 22 | , m_zRotate(0) 23 | , m_fps(0) 24 | { 25 | connect(this, &Item::xRotateChanged, [=]() { update(); }); 26 | connect(this, &Item::yRotateChanged, [=]() { update(); }); 27 | connect(this, &Item::zRotateChanged, [=]() { update(); }); 28 | 29 | connect(this, &Item::fullChanged, [&]() { 30 | if (full()) 31 | { 32 | m_size.setWidth(this->width()); 33 | m_size.setHeight(this->height()); 34 | m_pos = this->position(); 35 | this->setPosition(QPointF(0, 0)); 36 | this->setWidth(QApplication::desktop()->width()); 37 | this->setHeight(QApplication::desktop()->height()); 38 | } 39 | else 40 | { 41 | setPosition(m_pos); 42 | this->setWidth(m_size.width()); 43 | this->setHeight(m_size.height()); 44 | } 45 | }); 46 | startTimer(1000 / 60); 47 | } 48 | void timerEvent(QTimerEvent*) 49 | { 50 | update(); 51 | } 52 | Renderer* createRenderer() const override; 53 | 54 | qreal xRotate() const 55 | { 56 | return m_xRotate; 57 | } 58 | qreal yRotate() const 59 | { 60 | return m_yRotate; 61 | } 62 | qreal zRotate() const 63 | { 64 | return m_zRotate; 65 | } 66 | qreal fps() const 67 | { 68 | return m_fps; 69 | } 70 | bool full() const 71 | { 72 | return m_full; 73 | } 74 | 75 | void setXRotate(qreal v) 76 | { 77 | if (v == m_xRotate) 78 | return; 79 | m_xRotate = v; 80 | emit xRotateChanged(); 81 | } 82 | void setYRotate(qreal v) 83 | { 84 | if (v == m_yRotate) 85 | return; 86 | m_yRotate = v; 87 | emit yRotateChanged(); 88 | } 89 | void setZRotate(qreal v) 90 | { 91 | if (v == m_zRotate) 92 | return; 93 | m_zRotate = v; 94 | emit zRotateChanged(); 95 | } 96 | 97 | void updateFPS(qreal fps) 98 | { 99 | m_fps = fps; 100 | emit fpsChanged(); 101 | } 102 | void setFull(bool v) 103 | { 104 | if (v == m_full) 105 | return; 106 | m_full = v; 107 | emit fullChanged(); 108 | } 109 | signals: 110 | void xRotateChanged(); 111 | void yRotateChanged(); 112 | void zRotateChanged(); 113 | void fpsChanged(); 114 | void fullChanged(); 115 | 116 | private: 117 | qreal m_xRotate; 118 | qreal m_yRotate; 119 | qreal m_zRotate; 120 | qreal m_fps; 121 | bool m_full; 122 | QSize m_size; 123 | QPointF m_pos; 124 | }; 125 | 126 | #endif // SHADER_H 127 | -------------------------------------------------------------------------------- /FrameBufferObject/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "item.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | int main(int argc, char* argv[]) 7 | { 8 | // QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 9 | qSetMessagePattern("log[%{file} %{function} %{line}] %{message}"); 10 | QApplication app(argc, argv); 11 | 12 | qmlRegisterType("TaoItem", 1, 0, "TaoItem"); 13 | QQuickView view; 14 | view.setResizeMode(QQuickView::SizeRootObjectToView); 15 | view.setSource(QUrl(QLatin1Literal("qrc:/qml/main.qml"))); 16 | QObject::connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit())); 17 | view.show(); 18 | 19 | return app.exec(); 20 | } 21 | -------------------------------------------------------------------------------- /FrameBufferObject/src/render.cpp: -------------------------------------------------------------------------------- 1 | #include "render.h" 2 | #include "easy.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | Render::Render() 8 | : m_texture(0) 9 | { 10 | fps = 60.0; 11 | angleInDegrees = 0; 12 | } 13 | Render::~Render() 14 | { 15 | SafeDeletePtr(m_texture); 16 | } 17 | 18 | void Render::init() 19 | { 20 | initializeOpenGLFunctions(); 21 | initShaders(); 22 | initData(); 23 | initTextures(); 24 | 25 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 26 | glEnable(GL_TEXTURE_2D); 27 | glEnable(GL_DEPTH_TEST); 28 | } 29 | void Render::setRotate(qreal x, qreal y, qreal z) 30 | { 31 | mModelMatrix.setToIdentity(); 32 | // mModelMatrix.translate(0, 0, -0.5); 33 | // if (x) 34 | mModelMatrix.rotate(x, 1, 0, 0); 35 | // if (y) 36 | mModelMatrix.rotate(y, 0, 1, 0); 37 | // if (z) 38 | mModelMatrix.rotate(z, 0, 0, 1); 39 | } 40 | qreal Render::getFPS() 41 | { 42 | return fps; 43 | } 44 | void Render::initShaders() 45 | { 46 | if (!m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vertex.glsl")) 47 | { 48 | qDebug() << " add vertex shader file failed." << m_program.log(); 49 | return; 50 | } 51 | if (!m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fragment.glsl")) 52 | { 53 | qDebug() << " add fragment shader file failed." << m_program.log(); 54 | return; 55 | } 56 | m_program.link(); 57 | m_program.bind(); 58 | 59 | mMVPMatrixHandle = m_program.uniformLocation("qt_ModelViewProjectionMatrix"); 60 | mVerticesHandle = m_program.attributeLocation("qt_Vertex"); 61 | mColorsHandle = m_program.attributeLocation("a_Color"); 62 | mTexCoordHandle = m_program.attributeLocation("qt_MultiTexCoord0"); 63 | } 64 | void Render::initTextures() 65 | { 66 | SafeDeletePtr(m_texture); 67 | m_texture = new QOpenGLTexture(QImage(":/img/s.jpg")); 68 | m_texture->setMinificationFilter(QOpenGLTexture::Linear); 69 | m_texture->setMagnificationFilter(QOpenGLTexture::Linear); 70 | m_texture->setWrapMode(QOpenGLTexture::Repeat); 71 | } 72 | 73 | void Render::initData() 74 | { 75 | vertices << QVector3D(-1, -1, 0.0f) << QVector3D(1, -1, 0.0f) << QVector3D(1, 1, 0.0f) << QVector3D(-1, 1, 0.0f); 76 | texcoords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1); 77 | colors << QVector4D(1.0f, 0.0f, 0.0f, 1.0f) << QVector4D(0.0f, 0.0f, 1.0f, 1.0f) << QVector4D(0.0f, 1.0f, 0.0f, 1.0f); 78 | mViewMatrix.setToIdentity(); 79 | mViewMatrix.lookAt(QVector3D(0.0f, 0.0f, 1.001f), QVector3D(0.0f, 0.0f, -5.0f), QVector3D(0.0f, 1.0f, 0.0f)); 80 | 81 | mModelMatrix.setToIdentity(); 82 | mProjectionMatrix.setToIdentity(); 83 | mProjectionMatrix.frustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 10.0f); 84 | } 85 | void Render::paint() 86 | { 87 | glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 88 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 89 | 90 | m_program.bind(); 91 | draw(); 92 | m_program.release(); 93 | 94 | calcFPS(); 95 | } 96 | 97 | void Render::draw() 98 | { 99 | //顶点 100 | m_program.enableAttributeArray(mVerticesHandle); 101 | m_program.setAttributeArray(mVerticesHandle, vertices.constData()); 102 | //颜色 103 | m_program.enableAttributeArray(mColorsHandle); 104 | m_program.setAttributeArray(mColorsHandle, colors.constData()); 105 | //纹理坐标 106 | m_program.enableAttributeArray(mTexCoordHandle); 107 | m_program.setAttributeArray(mTexCoordHandle, texcoords.constData()); 108 | // //MVP矩阵 109 | 110 | mModelMatrix.rotate(angleInDegrees, 0, 0, 1); 111 | angleInDegrees = (angleInDegrees + 1) % 360; 112 | mMVPMatrix = mProjectionMatrix * mViewMatrix * mModelMatrix; 113 | m_program.setUniformValue(mMVPMatrixHandle, mMVPMatrix); 114 | 115 | //纹理 116 | m_texture->bind(); 117 | m_program.setUniformValue("qt_Texture0", 0); 118 | 119 | glDrawArrays(GL_TRIANGLE_FAN, 0, vertices.size()); 120 | m_texture->release(); 121 | m_program.disableAttributeArray(mVerticesHandle); 122 | m_program.disableAttributeArray(mColorsHandle); 123 | } 124 | 125 | void Render::calcFPS() 126 | { 127 | static QTime time; 128 | static int once = [=]() { 129 | time.start(); 130 | return 0; 131 | }(); 132 | Q_UNUSED(once) 133 | static int frame = 0; 134 | frame++; 135 | if (frame > 10) 136 | { 137 | qreal elasped = time.elapsed(); 138 | updateFPS(frame * 1000.0 / elasped); 139 | time.restart(); 140 | frame = 0; 141 | } 142 | } 143 | void Render::updateFPS(float v) 144 | { 145 | fps = v; 146 | // qDebug() << "fps " << fps; 147 | } 148 | -------------------------------------------------------------------------------- /FrameBufferObject/src/render.h: -------------------------------------------------------------------------------- 1 | #ifndef RENDER_H 2 | #define RENDER_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class Render : protected QOpenGLExtraFunctions 13 | { 14 | public: 15 | Render(); 16 | ~Render(); 17 | 18 | void init(); 19 | void paint(); 20 | void setRotate(qreal x, qreal y, qreal z); 21 | 22 | qreal getFPS(); 23 | 24 | private: 25 | void initShaders(); 26 | void initTextures(); 27 | void initData(); 28 | 29 | void draw(); 30 | 31 | void calcFPS(); 32 | void updateFPS(float); 33 | 34 | QOpenGLShaderProgram m_program; 35 | 36 | QOpenGLTexture* m_texture; 37 | 38 | QVector vertices; 39 | QVector colors; 40 | QVector texcoords; 41 | int mMVPMatrixHandle; 42 | int mVerticesHandle; 43 | int mColorsHandle; 44 | int mTexCoordHandle; 45 | 46 | QMatrix4x4 mModelMatrix; 47 | QMatrix4x4 mViewMatrix; 48 | QMatrix4x4 mProjectionMatrix; 49 | QMatrix4x4 mMVPMatrix; 50 | 51 | qreal fps; 52 | int angleInDegrees; 53 | }; 54 | 55 | #endif // RENDER_H 56 | -------------------------------------------------------------------------------- /GLSL.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | CONFIG += ordered 3 | SUBDIRS += \ 4 | HelloTexture \ 5 | HelloMix \ 6 | HelloCube \ 7 | HelloFBO \ 8 | QuickOpenGL \ 9 | light \ 10 | lightCasters \ 11 | mulitLight \ 12 | FrameBufferObject \ 13 | material \ 14 | DepthTest \ 15 | SkyBox \ 16 | Instance \ 17 | Instance2 \ 18 | Instance-Texture 19 | 20 | OTHER_FILES += \ 21 | README.md \ 22 | .clang-format \ 23 | LICENSE \ 24 | .github/workflows/*.yml 25 | -------------------------------------------------------------------------------- /HelloCube/HelloCube.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-09-22T10:04:40 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui widgets 8 | 9 | CONFIG += c+=11 10 | TEMPLATE = app 11 | 12 | HEADERS += \ 13 | src/cube.h \ 14 | src/window.h 15 | 16 | SOURCES += \ 17 | src/cube.cpp \ 18 | src/main.cpp \ 19 | src/window.cpp 20 | 21 | RESOURCES += \ 22 | res/shader.qrc \ 23 | res/texture.qrc 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /HelloCube/res/image/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloCube/res/image/cube.png -------------------------------------------------------------------------------- /HelloCube/res/image/cube1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloCube/res/image/cube1.png -------------------------------------------------------------------------------- /HelloCube/res/image/w1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloCube/res/image/w1.png -------------------------------------------------------------------------------- /HelloCube/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fshader.glsl 4 | shader/vshader.glsl 5 | 6 | 7 | -------------------------------------------------------------------------------- /HelloCube/res/shader/fshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | uniform sampler2D texture; 8 | 9 | varying vec2 v_texcoord; 10 | 11 | //! [0] 12 | void main() 13 | { 14 | // Set fragment color from texture 15 | gl_FragColor = texture2D(texture, v_texcoord); 16 | } 17 | //! [0] 18 | 19 | -------------------------------------------------------------------------------- /HelloCube/res/shader/vshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | uniform mat4 mvp_matrix; 8 | 9 | attribute vec4 a_position; 10 | attribute vec2 a_texcoord; 11 | 12 | varying vec2 v_texcoord; 13 | 14 | //! [0] 15 | void main() 16 | { 17 | // Calculate vertex position in screen space 18 | gl_Position = mvp_matrix * a_position; 19 | 20 | // Pass texture coordinate to fragment shader 21 | // Value will be automatically interpolated to fragments inside polygon faces 22 | v_texcoord = a_texcoord; 23 | } 24 | //! [0] 25 | -------------------------------------------------------------------------------- /HelloCube/res/texture.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/cube.png 4 | image/cube1.png 5 | image/w1.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /HelloCube/src/cube.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_H 2 | #define CUBE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Cube : protected QOpenGLFunctions 9 | { 10 | public: 11 | Cube(); 12 | virtual ~Cube(); 13 | void drawCube(QOpenGLShaderProgram* program); 14 | 15 | private: 16 | void initCube(); 17 | 18 | QOpenGLBuffer arrayBuf; 19 | QOpenGLBuffer indexBuf; 20 | }; 21 | 22 | #endif // CUBE_H 23 | -------------------------------------------------------------------------------- /HelloCube/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef QT_NO_OPENGL 6 | #include "window.h" 7 | #endif 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | QApplication app(argc, argv); 12 | 13 | QSurfaceFormat format; 14 | format.setDepthBufferSize(24); 15 | QSurfaceFormat::setDefaultFormat(format); 16 | 17 | app.setApplicationName("cube"); 18 | app.setApplicationVersion("0.1"); 19 | #ifndef QT_NO_OPENGL 20 | Window win; 21 | win.show(); 22 | #else 23 | QLabel note("OpenGL Support required"); 24 | note.show(); 25 | #endif 26 | return app.exec(); 27 | } 28 | -------------------------------------------------------------------------------- /HelloCube/src/window.cpp: -------------------------------------------------------------------------------- 1 | #include "window.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | Window::Window(QWidget* parent) 9 | : QOpenGLWidget(parent) 10 | , cube(0) 11 | , texture(0) 12 | , angularSpeed(0) 13 | { 14 | fps = 60.0; 15 | } 16 | Window::~Window() 17 | { 18 | makeCurrent(); 19 | delete texture; 20 | delete cube; 21 | doneCurrent(); 22 | } 23 | void Window::mousePressEvent(QMouseEvent* e) 24 | { 25 | // Save mouse press position 26 | mousePressPosition = QVector2D(e->localPos()); 27 | } 28 | void Window::mouseReleaseEvent(QMouseEvent* e) 29 | { 30 | // Mouse release position - mouse press position 31 | QVector2D diff = QVector2D(e->localPos()) - mousePressPosition; 32 | 33 | // Rotation axis is perpendicular to the mouse position difference 34 | // vector 35 | QVector3D n = QVector3D(diff.y(), diff.x(), 0.0).normalized(); 36 | 37 | // Accelerate angular speed relative to the length of the mouse sweep 38 | qreal acc = diff.length() / 100.0; 39 | 40 | // Calculate new rotation axis as weighted sum 41 | rotationAxis = (rotationAxis * angularSpeed + n * acc).normalized(); 42 | 43 | // Increase angular speed 44 | angularSpeed += acc; 45 | } 46 | void Window::timerEvent(QTimerEvent*) 47 | { 48 | // Decrease angular speed (friction) 49 | angularSpeed *= 0.99; 50 | 51 | // Stop rotation when speed goes below threshold 52 | if (angularSpeed < 0.01) 53 | { 54 | angularSpeed = 0.0; 55 | } 56 | else 57 | { 58 | // Update rotation 59 | rotation = QQuaternion::fromAxisAndAngle(rotationAxis, angularSpeed) * rotation; 60 | // Request an update 61 | update(); 62 | } 63 | } 64 | void Window::initializeGL() 65 | { 66 | initializeOpenGLFunctions(); 67 | 68 | glClearColor(0, 0, 0, 1); 69 | 70 | initShaders(); 71 | initTextures(); 72 | 73 | // glEnable(GL_DEPTH_TEST); 74 | 75 | glEnable(GL_CULL_FACE); 76 | 77 | cube = new Cube; 78 | 79 | startTimer(12); 80 | // timer.start(12, this); 81 | } 82 | void Window::initShaders() 83 | { 84 | if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vshader.glsl")) 85 | { 86 | qDebug() << __FILE__ << __FUNCTION__ << " add vertex shader file failed."; 87 | close(); 88 | } 89 | if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fshader.glsl")) 90 | { 91 | qDebug() << __FILE__ << __FUNCTION__ << " add fragment shader file failed."; 92 | close(); 93 | } 94 | 95 | if (!program.link()) 96 | { 97 | qDebug() << __FILE__ << __LINE__ << "program link failed"; 98 | close(); 99 | } 100 | if (!program.bind()) 101 | { 102 | qDebug() << __FILE__ << __LINE__ << "program bind failed"; 103 | close(); 104 | } 105 | } 106 | void Window::initTextures() 107 | { 108 | texture = new QOpenGLTexture(QImage(":/image/cube.png").mirrored()); 109 | texture->setMinificationFilter(QOpenGLTexture::Nearest); 110 | texture->setMagnificationFilter(QOpenGLTexture::Linear); 111 | texture->setWrapMode(QOpenGLTexture::Repeat); 112 | } 113 | 114 | void Window::resizeGL(int w, int h) 115 | { 116 | // Calculate aspect ratio 117 | qreal aspect = qreal(w) / qreal(h ? h : 1); 118 | 119 | // Set near plane to 3.0, far plane to 7.0, field of view 45 degrees 120 | const qreal zNear = 3.0, zFar = 7.0, fov = 45.0; 121 | 122 | // Reset projection 123 | projection.setToIdentity(); 124 | // Set perspective projection 125 | projection.perspective(fov, aspect, zNear, zFar); 126 | } 127 | 128 | void Window::paintGL() 129 | { 130 | glClear(GL_COLOR_BUFFER_BIT); 131 | // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 132 | 133 | texture->bind(); 134 | 135 | QMatrix4x4 matrix; 136 | matrix.translate(0.0, 0.0, -5.0); 137 | matrix.rotate(rotation); 138 | 139 | program.setUniformValue("mvp_matrix", projection * matrix); 140 | 141 | program.setUniformValue("texture", 0); 142 | 143 | cube->drawCube(&program); 144 | 145 | calcFPS(); 146 | paintFPS(); 147 | } 148 | 149 | void Window::calcFPS() 150 | { 151 | static QTime time; 152 | static int once = [=]() { 153 | time.start(); 154 | return 0; 155 | }(); 156 | Q_UNUSED(once) 157 | static int frame = 0; 158 | if (frame++ > 100) 159 | { 160 | qreal elasped = time.elapsed(); 161 | updateFPS(frame / elasped * 1000); 162 | time.restart(); 163 | frame = 0; 164 | } 165 | } 166 | void Window::updateFPS(qreal v) 167 | { 168 | fps = v; 169 | } 170 | void Window::paintFPS() 171 | { 172 | // QString str = QString("FPS:%1").arg(QString::number(fps, 'f', 3)); 173 | // this->setWindowTitle(str); 174 | } 175 | -------------------------------------------------------------------------------- /HelloCube/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include "cube.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | class Cube; 16 | 17 | class Window 18 | : public QOpenGLWidget 19 | , protected QOpenGLFunctions 20 | { 21 | Q_OBJECT 22 | public: 23 | explicit Window(QWidget* parent = 0); 24 | ~Window(); 25 | 26 | protected: 27 | void mousePressEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 28 | void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 29 | void timerEvent(QTimerEvent* e) Q_DECL_OVERRIDE; 30 | 31 | void initializeGL() Q_DECL_OVERRIDE; 32 | void paintGL() Q_DECL_OVERRIDE; 33 | void resizeGL(int w, int h) Q_DECL_OVERRIDE; 34 | 35 | void initShaders(); 36 | void initTextures(); 37 | 38 | private: 39 | void calcFPS(); 40 | void updateFPS(qreal); 41 | void paintFPS(); 42 | 43 | private: 44 | QBasicTimer timer; 45 | QOpenGLShaderProgram program; 46 | Cube* cube; 47 | 48 | QOpenGLTexture* texture; 49 | 50 | QMatrix4x4 projection; 51 | 52 | QVector2D mousePressPosition; 53 | QVector3D rotationAxis; 54 | qreal angularSpeed; 55 | QQuaternion rotation; 56 | qreal fps; 57 | }; 58 | 59 | #endif // WINDOW_H 60 | -------------------------------------------------------------------------------- /HelloFBO/HelloFBO.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-09-22T10:04:40 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | CONFIG += c+=11 10 | TEMPLATE = app 11 | 12 | HEADERS += \ 13 | src/cube.h \ 14 | src/window.h 15 | 16 | SOURCES += \ 17 | src/cube.cpp \ 18 | src/main.cpp \ 19 | src/window.cpp 20 | 21 | RESOURCES += \ 22 | res/shader.qrc \ 23 | res/texture.qrc 24 | 25 | 26 | CONFIG(debug) { 27 | DEFINES += DEBUG_GL 28 | } 29 | -------------------------------------------------------------------------------- /HelloFBO/res/image/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloFBO/res/image/cube.png -------------------------------------------------------------------------------- /HelloFBO/res/image/cube1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloFBO/res/image/cube1.png -------------------------------------------------------------------------------- /HelloFBO/res/image/w1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloFBO/res/image/w1.png -------------------------------------------------------------------------------- /HelloFBO/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fshader.glsl 4 | shader/vshader.glsl 5 | shader/fFbo.glsl 6 | shader/vFbo.glsl 7 | 8 | 9 | -------------------------------------------------------------------------------- /HelloFBO/res/shader/fFbo.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D screenTexture; 7 | 8 | void main() 9 | { 10 | vec3 col = texture(screenTexture, TexCoords).rgb; 11 | FragColor = vec4(1.0 - col, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /HelloFBO/res/shader/fshader.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | #ifdef GL_ES 3 | // Set default precision to medium 4 | precision mediump int; 5 | precision mediump float; 6 | #endif 7 | 8 | uniform sampler2D texture; 9 | 10 | in vec2 v_texcoord; 11 | out vec4 FragColor; 12 | //! [0] 13 | void main() 14 | { 15 | // Set fragment color from texture 16 | FragColor = texture2D(texture, v_texcoord); 17 | } 18 | //! [0] 19 | 20 | -------------------------------------------------------------------------------- /HelloFBO/res/shader/vFbo.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec2 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | void main() 8 | { 9 | TexCoords = aTexCoords; 10 | gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /HelloFBO/res/shader/vshader.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | #ifdef GL_ES 3 | // Set default precision to medium 4 | precision mediump int; 5 | precision mediump float; 6 | #endif 7 | 8 | uniform mat4 mvp_matrix; 9 | 10 | layout(location = 0) in vec4 a_position; 11 | layout(location = 1) in vec2 a_texcoord; 12 | 13 | out vec2 v_texcoord; 14 | 15 | //! [0] 16 | void main() 17 | { 18 | // Calculate vertex position in screen space 19 | gl_Position = mvp_matrix * a_position; 20 | 21 | // Pass texture coordinate to fragment shader 22 | // Value will be automatically interpolated to fragments inside polygon faces 23 | v_texcoord = a_texcoord; 24 | } 25 | //! [0] 26 | -------------------------------------------------------------------------------- /HelloFBO/res/texture.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/cube.png 4 | image/cube1.png 5 | image/w1.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /HelloFBO/src/cube.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_H 2 | #define CUBE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Cube : protected QOpenGLExtraFunctions 9 | { 10 | public: 11 | Cube(); 12 | virtual ~Cube(); 13 | void initCube(QOpenGLShaderProgram* program); 14 | void drawCube(QOpenGLShaderProgram* program); 15 | 16 | private: 17 | QOpenGLBuffer arrayBuf; 18 | QOpenGLBuffer indexBuf; 19 | GLuint vao; 20 | }; 21 | 22 | #endif // CUBE_H 23 | -------------------------------------------------------------------------------- /HelloFBO/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "window.h" 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | 8 | QCoreApplication::setApplicationName("cube"); 9 | QCoreApplication::setApplicationVersion("0.1"); 10 | 11 | QGuiApplication app(argc, argv); 12 | 13 | QSurfaceFormat format = QSurfaceFormat::defaultFormat(); 14 | #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) 15 | format.setRenderableType(QSurfaceFormat::OpenGLES); 16 | format.setDepthBufferSize(24); 17 | format.setVersion(3, 1); 18 | format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); 19 | format.setSamples(8); 20 | #else 21 | 22 | format.setDepthBufferSize(24); 23 | format.setVersion(3, 3); 24 | format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); 25 | format.setSamples(8); 26 | #endif 27 | #ifdef DEBUG_GL 28 | format.setOption(QSurfaceFormat::DebugContext); 29 | #endif 30 | QSurfaceFormat::setDefaultFormat(format); 31 | 32 | Window win; 33 | win.show(); 34 | return app.exec(); 35 | } 36 | -------------------------------------------------------------------------------- /HelloFBO/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include "cube.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #ifdef DEBUG_GL 15 | #include 16 | #endif 17 | 18 | class Cube; 19 | 20 | class Window 21 | : public QOpenGLWindow 22 | , public QOpenGLExtraFunctions 23 | { 24 | Q_OBJECT 25 | public: 26 | explicit Window(QWindow* parent = nullptr); 27 | ~Window() override; 28 | 29 | protected: 30 | void mousePressEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 31 | void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 32 | void timerEvent(QTimerEvent* e) Q_DECL_OVERRIDE; 33 | 34 | void initializeGL() Q_DECL_OVERRIDE; 35 | void paintGL() Q_DECL_OVERRIDE; 36 | void resizeGL(int w, int h) Q_DECL_OVERRIDE; 37 | 38 | void initShaders(); 39 | void initTextures(); 40 | void initFBO(); 41 | void initQuad(); 42 | 43 | private: 44 | void calcFPS(); 45 | void updateFPS(qreal); 46 | void paintFPS(); 47 | void useCubeShader(); 48 | void useFBOShader(); 49 | 50 | private: 51 | QTimer timer; 52 | QOpenGLShaderProgram* cubeProgram = nullptr; 53 | QOpenGLShaderProgram* fboProgram = nullptr; 54 | QOpenGLShaderProgram* program = nullptr; 55 | Cube* cube = nullptr; 56 | 57 | QOpenGLTexture* texture = nullptr; 58 | 59 | QMatrix4x4 projection; 60 | 61 | QVector2D mousePressPosition; 62 | QVector3D rotationAxis; 63 | qreal angularSpeed; 64 | QQuaternion rotation; 65 | qreal fps; 66 | GLuint fbo; 67 | GLuint rbo; 68 | GLuint fboTexture; 69 | GLuint quadVAO; 70 | GLuint quadVBO; 71 | #ifdef DEBUG_GL 72 | QOpenGLDebugLogger* logger = nullptr; 73 | #endif 74 | }; 75 | 76 | #endif // WINDOW_H 77 | -------------------------------------------------------------------------------- /HelloMix/HelloMix.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-09-01T22:29:03 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | CONFIG +=c++11 11 | 12 | TEMPLATE = app 13 | 14 | HEADERS += \ 15 | src/window.h 16 | 17 | SOURCES += \ 18 | src/main.cpp \ 19 | src/window.cpp 20 | 21 | RESOURCES += \ 22 | res/res.qrc \ 23 | res/shader.qrc 24 | 25 | 26 | -------------------------------------------------------------------------------- /HelloMix/res/img/bj.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloMix/res/img/bj.jpg -------------------------------------------------------------------------------- /HelloMix/res/img/ha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloMix/res/img/ha.png -------------------------------------------------------------------------------- /HelloMix/res/img/pu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloMix/res/img/pu.png -------------------------------------------------------------------------------- /HelloMix/res/res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | img/bj.jpg 4 | img/ha.png 5 | img/pu.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /HelloMix/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fragment.fsh 4 | shader/vertex.vsh 5 | 6 | 7 | -------------------------------------------------------------------------------- /HelloMix/res/shader/fragment.fsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision highp int; 4 | precision highp float; 5 | #endif 6 | varying vec2 v_texCoord; 7 | uniform sampler2D u_texture1; 8 | uniform sampler2D u_texture2; 9 | uniform float mixPara; 10 | void main(void) 11 | { 12 | gl_FragColor = mix(texture2D(u_texture1, v_texCoord), texture2D(u_texture2, v_texCoord), mixPara); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /HelloMix/res/shader/vertex.vsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision highp int; 4 | precision highp float; 5 | #endif 6 | attribute highp vec3 qt_Vertex; 7 | attribute highp vec2 texCoord; 8 | 9 | uniform mat4 u_modelMatrix; 10 | uniform mat4 u_viewMatrix; 11 | uniform mat4 u_projectMatrix; 12 | 13 | varying vec2 v_texCoord; 14 | void main(void) 15 | { 16 | gl_Position = u_projectMatrix * u_viewMatrix * u_modelMatrix * vec4(qt_Vertex, 1.0f); 17 | v_texCoord = texCoord; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /HelloMix/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "window.h" 2 | #include 3 | #include 4 | int main(int argc, char* argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | // QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); 8 | // fmt.setMajorVersion(2); 9 | // fmt.setMinorVersion(0); 10 | // fmt.setProfile(QSurfaceFormat::CoreProfile); 11 | // QSurfaceFormat::setDefaultFormat(fmt); 12 | Window w; 13 | w.show(); 14 | 15 | return a.exec(); 16 | } 17 | -------------------------------------------------------------------------------- /HelloMix/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | class Window 13 | : public QOpenGLWidget 14 | , protected QOpenGLFunctions 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | Window(QWidget* parent = 0); 20 | ~Window(); 21 | 22 | protected: 23 | void initializeGL() override; 24 | void paintGL() override; 25 | void resizeGL(int w, int h) override; 26 | void timerEvent(QTimerEvent*) override; 27 | void keyPressEvent(QKeyEvent* event) override; 28 | void keyReleaseEvent(QKeyEvent* event) override; 29 | void mousePressEvent(QMouseEvent* event) override; 30 | void mouseMoveEvent(QMouseEvent* event) override; 31 | void wheelEvent(QWheelEvent* event) override; 32 | void calcFPS(); 33 | void updateFPS(qreal); 34 | void paintFPS(); 35 | void checkKey(); 36 | 37 | private: 38 | void makeObject(); 39 | void initShader(); 40 | void initTexture(); 41 | 42 | QOpenGLShaderProgram* program; 43 | QVector vertices; 44 | QVector cubePositions; 45 | QVector coords; 46 | 47 | QVector3D cameraPos; 48 | QVector3D cameraFront; 49 | QVector3D cameraUp; 50 | 51 | QMatrix4x4 modelMat, viewMat, projectMat; 52 | QOpenGLTexture *texture1, *texture2; 53 | int verticesHandle, coordHandle; 54 | qreal mixPara; 55 | QTime m_time; 56 | qreal fps; 57 | qreal elapsed; 58 | qreal yaw, pitch; 59 | qreal aspect; 60 | bool keys[1024]; 61 | QPoint last; 62 | }; 63 | 64 | #endif // WINDOW_H 65 | -------------------------------------------------------------------------------- /HelloTexture/HelloTexture.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | CONFIG += utf8_source 4 | TEMPLATE = app 5 | 6 | HEADERS += \ 7 | src/window.h 8 | 9 | SOURCES += \ 10 | src/main.cpp \ 11 | src/window.cpp 12 | 13 | RESOURCES += \ 14 | res/img.qrc \ 15 | res/shader.qrc 16 | 17 | include($$PWD/../Common/Common.pri) 18 | -------------------------------------------------------------------------------- /HelloTexture/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloTexture/demo.png -------------------------------------------------------------------------------- /HelloTexture/res/image/w1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloTexture/res/image/w1.png -------------------------------------------------------------------------------- /HelloTexture/res/image/w2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloTexture/res/image/w2.png -------------------------------------------------------------------------------- /HelloTexture/res/image/wood.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/HelloTexture/res/image/wood.jpg -------------------------------------------------------------------------------- /HelloTexture/res/img.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/w1.png 4 | image/w2.png 5 | image/wood.jpg 6 | 7 | 8 | -------------------------------------------------------------------------------- /HelloTexture/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fragment.fsh 4 | shader/vertex.vsh 5 | 6 | 7 | -------------------------------------------------------------------------------- /HelloTexture/res/shader/fragment.fsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision highp int; 4 | precision highp float; 5 | #endif 6 | uniform sampler2D qt_Texture0; 7 | varying highp vec4 qt_TexCoord0; 8 | varying vec4 v_Color; 9 | void main(void) 10 | { 11 | // gl_FragColor = v_Color; 12 | gl_FragColor = texture2D(qt_Texture0, qt_TexCoord0.st); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /HelloTexture/res/shader/vertex.vsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision highp int; 4 | precision highp float; 5 | #endif 6 | attribute highp vec4 qt_Vertex; 7 | attribute highp vec4 qt_MultiTexCoord0; 8 | attribute vec4 a_Color; 9 | uniform highp mat4 qt_ModelViewProjectionMatrix; 10 | varying highp vec4 qt_TexCoord0; 11 | varying vec4 v_Color; 12 | void main(void) 13 | { 14 | v_Color = a_Color; 15 | gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; 16 | qt_TexCoord0 = qt_MultiTexCoord0; 17 | } 18 | -------------------------------------------------------------------------------- /HelloTexture/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "GLCommon.h" 2 | #include "window.h" 3 | #include 4 | int main(int argc, char* argv[]) 5 | { 6 | GLCommon::prepareApp(); 7 | QGuiApplication a(argc, argv); 8 | GLCommon::prepareGL(); 9 | Window win; 10 | win.show(); 11 | return a.exec(); 12 | } 13 | -------------------------------------------------------------------------------- /HelloTexture/src/window.cpp: -------------------------------------------------------------------------------- 1 | #include "window.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | Window::Window(QWindow* parent) 7 | : GLWindow(NoPartialUpdate, parent) 8 | { 9 | angleInDegrees = 0; 10 | angleInDegrees += 0.3; 11 | } 12 | Window::~Window() { } 13 | void Window::initializeGL() 14 | { 15 | GLWindow::initializeGL(); 16 | resize(width(), height()); 17 | glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 18 | 19 | glEnable(GL_TEXTURE_2D); 20 | glEnable(GL_DEPTH_TEST); 21 | mModelMatrix.setToIdentity(); 22 | initTextures(); 23 | initShaders(); 24 | initData(); 25 | } 26 | void Window::keyPressEvent(QKeyEvent* event) 27 | { 28 | switch (event->key()) 29 | { 30 | 31 | case Qt::Key_A: 32 | { 33 | mModelMatrix.translate(-0.1f, 0, 0); 34 | update(); 35 | break; 36 | } 37 | case Qt::Key_D: 38 | { 39 | mModelMatrix.translate(0.1f, 0, 0); 40 | update(); 41 | break; 42 | } 43 | default: 44 | { 45 | break; 46 | } 47 | } 48 | } 49 | void Window::paintGL() 50 | { 51 | glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 52 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 53 | 54 | program.bind(); 55 | 56 | mModelMatrix.rotate(angleInDegrees, 0.0f, 0.0f, 1.0f); 57 | draw(); 58 | 59 | program.release(); 60 | 61 | GLWindow::paintGL(); 62 | paintFPS(); 63 | } 64 | 65 | void Window::draw() 66 | { 67 | //顶点 68 | program.enableAttributeArray(mVerticesHandle); 69 | program.setAttributeArray(mVerticesHandle, vertices.constData()); 70 | //颜色 71 | program.enableAttributeArray(mColorsHandle); 72 | program.setAttributeArray(mColorsHandle, colors.constData()); 73 | //纹理坐标 74 | program.enableAttributeArray(mTexCoordHandle); 75 | program.setAttributeArray(mTexCoordHandle, texcoords.constData()); 76 | // MVP矩阵 77 | mMVPMatrix = mProjectionMatrix * mViewMatrix * mModelMatrix; 78 | program.setUniformValue(mMVPMatrixHandle, mMVPMatrix); 79 | 80 | //纹理 81 | texture->bind(); 82 | program.setUniformValue("qt_Texture0", 0); 83 | 84 | glDrawArrays(GL_TRIANGLE_FAN, 0, vertices.size()); 85 | texture->release(); 86 | program.disableAttributeArray(mVerticesHandle); 87 | program.disableAttributeArray(mColorsHandle); 88 | } 89 | void Window::initData() 90 | { 91 | vertices << QVector3D(-1, -1, 0.0f) << QVector3D(1, -1, 0.0f) << QVector3D(1, 1, 0.0f) << QVector3D(-1, 1, 0.0f); 92 | texcoords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1); 93 | colors << QVector4D(1.0f, 0.0f, 0.0f, 1.0f) << QVector4D(0.0f, 0.0f, 1.0f, 1.0f) << QVector4D(0.0f, 1.0f, 0.0f, 1.0f); 94 | mViewMatrix.setToIdentity(); 95 | mViewMatrix.lookAt(QVector3D(0.0f, 0.0f, 1.001f), QVector3D(0.0f, 0.0f, -5.0f), QVector3D(0.0f, 1.0f, 0.0f)); 96 | } 97 | void Window::resizeGL(int w, int h) 98 | { 99 | GLWindow::resizeGL(w, h); 100 | glViewport(0, 0, w, h); 101 | 102 | float ratio = (float)w / h; 103 | float left = -ratio; 104 | float right = ratio; 105 | float bottom = -1.0f; 106 | float top = 1.0f; 107 | float n = 1.0f; 108 | float f = 10.0f; 109 | mProjectionMatrix.setToIdentity(); 110 | mProjectionMatrix.frustum(left, right, bottom, top, n, f); 111 | } 112 | 113 | void Window::paintFPS() 114 | { 115 | QPainter painter(this); 116 | painter.setPen(Qt::green); 117 | painter.setRenderHint(QPainter::TextAntialiasing); 118 | painter.drawText(10, 20, QString("FPS:%1").arg(QString::number(mFps, 'f', 3))); 119 | } 120 | 121 | void Window::initShaders() 122 | { 123 | if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vertex.vsh")) 124 | { 125 | qDebug() << __FILE__ << __FUNCTION__ << " add vertex shader file failed."; 126 | return; 127 | } 128 | if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fragment.fsh")) 129 | { 130 | qDebug() << __FILE__ << __FUNCTION__ << " add fragment shader file failed."; 131 | return; 132 | } 133 | program.bindAttributeLocation("qt_Vertex", 0); 134 | program.bindAttributeLocation("a_Color", 1); 135 | program.bindAttributeLocation("qt_MultiTexCoord0", 2); 136 | program.link(); 137 | program.bind(); 138 | 139 | mMVPMatrixHandle = program.uniformLocation("qt_ModelViewProjectionMatrix"); 140 | mVerticesHandle = program.attributeLocation("qt_Vertex"); 141 | mColorsHandle = program.attributeLocation("a_Color"); 142 | mTexCoordHandle = program.attributeLocation("qt_MultiTexCoord0"); 143 | } 144 | void Window::initTextures() 145 | { 146 | texture = new QOpenGLTexture(QImage(":/image/wood.jpg").mirrored()); 147 | texture->setMinificationFilter(QOpenGLTexture::Linear); 148 | texture->setMagnificationFilter(QOpenGLTexture::Linear); 149 | texture->setWrapMode(QOpenGLTexture::Repeat); 150 | } 151 | -------------------------------------------------------------------------------- /HelloTexture/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include "GLWindow.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | class Window : public GLWindow 12 | { 13 | Q_OBJECT 14 | public: 15 | Window(QWindow* parent = 0); 16 | ~Window(); 17 | 18 | protected: 19 | void initializeGL() Q_DECL_OVERRIDE; 20 | void paintGL() Q_DECL_OVERRIDE; 21 | void resizeGL(int w, int h) Q_DECL_OVERRIDE; 22 | void keyPressEvent(QKeyEvent* event) override; 23 | void initShaders(); 24 | void initTextures(); 25 | 26 | void initData(); 27 | void draw(); 28 | 29 | void paintFPS(); 30 | 31 | private: 32 | QOpenGLShaderProgram program; 33 | QOpenGLTexture* texture = nullptr; 34 | 35 | QVector vertices; 36 | QVector colors; 37 | QVector texcoords; 38 | int mMVPMatrixHandle = 0; 39 | int mVerticesHandle = 0; 40 | int mColorsHandle = 0; 41 | int mTexCoordHandle = 0; 42 | 43 | QMatrix4x4 mModelMatrix; 44 | QMatrix4x4 mViewMatrix; 45 | QMatrix4x4 mProjectionMatrix; 46 | QMatrix4x4 mMVPMatrix; 47 | 48 | qreal angleInDegrees; 49 | }; 50 | 51 | #endif // WINDOW_H 52 | -------------------------------------------------------------------------------- /Instance-Texture/Instance-Texture.pro: -------------------------------------------------------------------------------- 1 | QT += core gui widgets 2 | 3 | CONFIG +=c++11 4 | 5 | SOURCES += \ 6 | main.cpp \ 7 | mainWindow.cpp 8 | 9 | HEADERS += \ 10 | mainWindow.h 11 | RESOURCES += \ 12 | res.qrc 13 | -------------------------------------------------------------------------------- /Instance-Texture/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainWindow.h" 2 | #include 3 | #include 4 | int main(int argc, char* argv[]) 5 | { 6 | QApplication app(argc, argv); 7 | 8 | QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); 9 | fmt.setVersion(3, 3); 10 | fmt.setDepthBufferSize(24); 11 | fmt.setProfile(QSurfaceFormat::CoreProfile); 12 | #ifdef _DEBUG 13 | fmt.setOption(QSurfaceFormat::DebugContext); 14 | #endif 15 | QSurfaceFormat::setDefaultFormat(fmt); 16 | 17 | qWarning() << "fmt version" << fmt.version(); 18 | MainWindow w; 19 | w.showMaximized(); 20 | 21 | return app.exec(); 22 | } 23 | -------------------------------------------------------------------------------- /Instance-Texture/mainWindow.h: -------------------------------------------------------------------------------- 1 | #include "qnamespace.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | class MainWindow 10 | : public QOpenGLWidget 11 | , public QOpenGLFunctions_3_3_Core 12 | { 13 | Q_OBJECT 14 | using Super = QOpenGLWidget; 15 | 16 | public: 17 | MainWindow(QWidget* parent = nullptr); 18 | ~MainWindow(); 19 | 20 | protected: 21 | virtual void initializeGL() override; 22 | virtual void resizeGL(int w, int h) override; 23 | virtual void paintGL() override; 24 | virtual void timerEvent(QTimerEvent* e) override; 25 | 26 | private: 27 | void initVertices(); 28 | void updateVertices(); 29 | 30 | void calcFPS(); 31 | void updateFPS(qreal); 32 | void paintFPS(); 33 | 34 | private: 35 | #ifdef _DEBUG 36 | QOpenGLDebugLogger* mLogger = nullptr; 37 | #endif 38 | QOpenGLShaderProgram* mProgram = nullptr; 39 | GLuint mVerticesVBO = 0; 40 | GLuint mInstanceVBO = 0; 41 | GLuint mTexCoordsVBO = 0; 42 | GLuint mVAO = 0; 43 | QColor mColor = Qt::red; 44 | QVector mVertices; 45 | QMatrix4x4 mMVPMat; 46 | QVector mInstanceMats; 47 | QVector mTexCoords; 48 | QOpenGLTexture* mTexture; 49 | qreal mFPS = 60.0; 50 | }; 51 | -------------------------------------------------------------------------------- /Instance-Texture/pu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/Instance-Texture/pu.png -------------------------------------------------------------------------------- /Instance-Texture/res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | pu.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /Instance/Instance.pro: -------------------------------------------------------------------------------- 1 | QT += core gui widgets 2 | 3 | CONFIG +=c++11 4 | 5 | SOURCES += \ 6 | main.cpp \ 7 | mainWindow.cpp 8 | 9 | HEADERS += \ 10 | mainWindow.h 11 | -------------------------------------------------------------------------------- /Instance/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainWindow.h" 2 | #include 3 | #include 4 | int main(int argc, char* argv[]) 5 | { 6 | QApplication app(argc, argv); 7 | 8 | QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); 9 | fmt.setVersion(3, 3); 10 | fmt.setDepthBufferSize(24); 11 | fmt.setProfile(QSurfaceFormat::CoreProfile); 12 | #ifdef _DEBUG 13 | fmt.setOption(QSurfaceFormat::DebugContext); 14 | #endif 15 | QSurfaceFormat::setDefaultFormat(fmt); 16 | 17 | qWarning() << "fmt version" << fmt.version(); 18 | MainWindow w; 19 | w.show(); 20 | 21 | return app.exec(); 22 | } 23 | -------------------------------------------------------------------------------- /Instance/mainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainWindow.h" 2 | #include "qopenglext.h" 3 | #include 4 | static const QString sVertexShader = u8R"( 5 | #version 330 6 | 7 | #ifdef GL_ES 8 | // Set default precision to medium 9 | precision highp int; 10 | precision highp float; 11 | #endif 12 | 13 | layout (location = 0) in vec3 qt_Vertex; 14 | layout (location = 1) in vec2 qt_Offset; 15 | 16 | void main(void) 17 | { 18 | gl_Position = vec4(qt_Vertex + vec3(qt_Offset, 0.0), 1.0); 19 | } 20 | )"; 21 | 22 | static const QString sFragmentShader = u8R"( 23 | #version 330 24 | 25 | #ifdef GL_ES 26 | // Set default precision to medium 27 | precision highp int; 28 | precision highp float; 29 | #endif 30 | 31 | uniform vec4 outColor0; 32 | out vec4 fragColor; 33 | void main(void) 34 | { 35 | fragColor = outColor0; 36 | } 37 | )"; 38 | MainWindow::MainWindow(QWidget* parent) 39 | : Super(parent) 40 | { 41 | } 42 | 43 | MainWindow::~MainWindow() 44 | { 45 | makeCurrent(); 46 | #ifdef _DEBUG 47 | if (mLogger) 48 | { 49 | 50 | mLogger->stopLogging(); 51 | delete mLogger; 52 | mLogger = nullptr; 53 | } 54 | #endif 55 | doneCurrent(); 56 | } 57 | 58 | void MainWindow::initializeGL() 59 | { 60 | initializeOpenGLFunctions(); 61 | #ifdef _DEBUG 62 | mLogger = new QOpenGLDebugLogger(this); 63 | mLogger->initialize(); 64 | connect(mLogger, &QOpenGLDebugLogger::messageLogged, this, [this](const QOpenGLDebugMessage& msg) { qWarning() << msg.message(); }); 65 | mLogger->startLogging(); 66 | #endif 67 | 68 | glClearColor(0.2, 0.3, 0.4, 1); 69 | 70 | mProgram = new QOpenGLShaderProgram(this); 71 | if (!mProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, sVertexShader)) 72 | { 73 | qWarning() << mProgram->log(); 74 | return; 75 | } 76 | if (!mProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, sFragmentShader)) 77 | { 78 | qWarning() << mProgram->log(); 79 | return; 80 | } 81 | if (!mProgram->link()) 82 | { 83 | qWarning() << mProgram->log(); 84 | return; 85 | } 86 | mVertices = { 87 | QVector3D { -0.05, -0.05, 1.0 }, 88 | QVector3D { -0.05, 0.05, 1.0 }, 89 | QVector3D { 0.05, 0.05, 1.0 }, 90 | QVector3D { 0.05, -0.05, 1.0 }, 91 | }; 92 | 93 | float offset = 0.1f; 94 | 95 | for (int i = -10; i < 10; i += 2) 96 | { 97 | for (int j = -10; j < 10; j += 2) 98 | { 99 | mOffsets.append(QVector2D(i / 10.0f + offset, j / 10.0f + offset)); 100 | } 101 | } 102 | { 103 | // 生成顶点VBO 104 | glGenBuffers(1, &mVerticesVBO); 105 | // 生成实例VBO 106 | glGenBuffers(1, &mInstanceVBO); 107 | // 生成VAO 108 | glGenVertexArrays(1, &mVAO); 109 | 110 | // 顶点Buffer 写入数据 111 | glBindBuffer(GL_ARRAY_BUFFER, mVerticesVBO); 112 | { 113 | glBufferData(GL_ARRAY_BUFFER, sizeof(QVector3D) * mVertices.size(), mVertices.constData(), GL_STATIC_DRAW); 114 | } 115 | glBindBuffer(GL_ARRAY_BUFFER, 0); 116 | 117 | // 实例Buffer 写入数据 118 | glBindBuffer(GL_ARRAY_BUFFER, mInstanceVBO); 119 | { 120 | glBufferData(GL_ARRAY_BUFFER, sizeof(QVector2D) * mOffsets.size(), mOffsets.constData(), GL_STATIC_DRAW); 121 | } 122 | glBindBuffer(GL_ARRAY_BUFFER, 0); 123 | 124 | const uint32_t vertexLocation = 0; 125 | const uint32_t offsetLocation = 1; 126 | glBindVertexArray(mVAO); 127 | { 128 | // 顶点Buffer配置 129 | glEnableVertexAttribArray(vertexLocation); 130 | glBindBuffer(GL_ARRAY_BUFFER, mVerticesVBO); 131 | glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(QVector3D), (void*)0); 132 | 133 | // 实例Buffer配置 134 | glEnableVertexAttribArray(offsetLocation); 135 | glBindBuffer(GL_ARRAY_BUFFER, mInstanceVBO); 136 | glVertexAttribPointer(offsetLocation, 2, GL_FLOAT, GL_FALSE, sizeof(QVector2D), (void*)0); 137 | glBindBuffer(GL_ARRAY_BUFFER, 0); 138 | // 实例Buffer 除数配置 139 | glVertexAttribDivisor(offsetLocation, 1); 140 | } 141 | glBindVertexArray(0); 142 | } 143 | startTimer(1000 / 60); 144 | } 145 | 146 | void MainWindow::resizeGL(int w, int h) 147 | { 148 | glViewport(0, 0, w, h); 149 | Super::resizeGL(w, h); 150 | } 151 | 152 | void MainWindow::paintGL() 153 | { 154 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 155 | glClearColor(0.2, 0.3, 0.4, 1); 156 | if (!mProgram->bind()) 157 | { 158 | qWarning() << mProgram->log(); 159 | return; 160 | } 161 | mProgram->setUniformValue("outColor0", mColor); 162 | glBindVertexArray(mVAO); 163 | { 164 | glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, mOffsets.size()); 165 | } 166 | glBindVertexArray(0); 167 | } 168 | 169 | void MainWindow::timerEvent(QTimerEvent* e) 170 | { 171 | if (isVisible()) 172 | { 173 | update(); 174 | } 175 | } 176 | 177 | void MainWindow::initVertices() 178 | { 179 | // mCount = 2; 180 | // qreal x = 0.01; 181 | // qreal y = 0.01; 182 | // qreal w = 0.03; 183 | // qreal h = 0.02; 184 | // qreal xOffset = 0.01; 185 | // qreal yOffset = 0.01; 186 | // mVertices.clear(); 187 | // for (int i = 0; i < mCount; i++) 188 | // { 189 | // mVertices << QVector3D(x, y, 0.0); 190 | // mVertices << QVector3D(x + w, y, 0.0); 191 | // mVertices << QVector3D(x + w, y + h, 0.0); 192 | // mVertices << QVector3D(x, y + h, 0.0); 193 | // x += xOffset; 194 | // if (x + w >= 1.0) 195 | // { 196 | // x = 0.01; 197 | // y += yOffset; 198 | // } 199 | // } 200 | } 201 | 202 | void MainWindow::updateVertices() { } 203 | -------------------------------------------------------------------------------- /Instance/mainWindow.h: -------------------------------------------------------------------------------- 1 | #include "qnamespace.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | class MainWindow 9 | : public QOpenGLWidget 10 | , public QOpenGLFunctions_3_3_Core 11 | { 12 | Q_OBJECT 13 | using Super = QOpenGLWidget; 14 | 15 | public: 16 | MainWindow(QWidget* parent = nullptr); 17 | ~MainWindow(); 18 | 19 | protected: 20 | virtual void initializeGL() override; 21 | virtual void resizeGL(int w, int h) override; 22 | virtual void paintGL() override; 23 | virtual void timerEvent(QTimerEvent* e) override; 24 | 25 | private: 26 | void initVertices(); 27 | void updateVertices(); 28 | 29 | private: 30 | #ifdef _DEBUG 31 | QOpenGLDebugLogger* mLogger = nullptr; 32 | #endif 33 | QOpenGLShaderProgram* mProgram = nullptr; 34 | GLuint mVerticesVBO = 0; 35 | GLuint mInstanceVBO = 0; 36 | GLuint mVAO = 0; 37 | QColor mColor = Qt::red; 38 | QVector mVertices; 39 | QVector mOffsets; 40 | }; 41 | -------------------------------------------------------------------------------- /Instance2/Instance2.pro: -------------------------------------------------------------------------------- 1 | QT += core gui widgets 2 | 3 | CONFIG +=c++11 4 | 5 | SOURCES += \ 6 | main.cpp \ 7 | mainWindow.cpp 8 | 9 | HEADERS += \ 10 | mainWindow.h 11 | -------------------------------------------------------------------------------- /Instance2/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainWindow.h" 2 | #include 3 | #include 4 | int main(int argc, char* argv[]) 5 | { 6 | QApplication app(argc, argv); 7 | 8 | QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); 9 | fmt.setVersion(3, 3); 10 | fmt.setDepthBufferSize(24); 11 | fmt.setProfile(QSurfaceFormat::CoreProfile); 12 | #ifdef _DEBUG 13 | fmt.setOption(QSurfaceFormat::DebugContext); 14 | #endif 15 | QSurfaceFormat::setDefaultFormat(fmt); 16 | 17 | qWarning() << "fmt version" << fmt.version(); 18 | MainWindow w; 19 | w.showMaximized(); 20 | 21 | return app.exec(); 22 | } 23 | -------------------------------------------------------------------------------- /Instance2/mainWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainWindow.h" 2 | #include "qopenglext.h" 3 | #include 4 | #include 5 | static const QString sVertexShader = u8R"( 6 | #version 330 7 | 8 | #ifdef GL_ES 9 | // Set default precision to medium 10 | precision highp int; 11 | precision highp float; 12 | #endif 13 | 14 | layout (location = 0) in vec3 qt_Vertex; 15 | layout (location = 1) in mat4 qt_InstanceMatrix; 16 | 17 | uniform mat4 mvpMatrix; 18 | void main(void) 19 | { 20 | gl_Position = mvpMatrix * qt_InstanceMatrix *vec4(qt_Vertex, 1.0); 21 | } 22 | )"; 23 | 24 | static const QString sFragmentShader = u8R"( 25 | #version 330 26 | 27 | #ifdef GL_ES 28 | // Set default precision to medium 29 | precision highp int; 30 | precision highp float; 31 | #endif 32 | 33 | uniform vec4 outColor0; 34 | out vec4 fragColor; 35 | void main(void) 36 | { 37 | fragColor = outColor0; 38 | } 39 | )"; 40 | MainWindow::MainWindow(QWidget* parent) 41 | : Super(parent) 42 | { 43 | } 44 | 45 | MainWindow::~MainWindow() 46 | { 47 | makeCurrent(); 48 | #ifdef _DEBUG 49 | if (mLogger) 50 | { 51 | 52 | mLogger->stopLogging(); 53 | delete mLogger; 54 | mLogger = nullptr; 55 | } 56 | #endif 57 | doneCurrent(); 58 | } 59 | 60 | void MainWindow::initializeGL() 61 | { 62 | initializeOpenGLFunctions(); 63 | #ifdef _DEBUG 64 | mLogger = new QOpenGLDebugLogger(this); 65 | mLogger->initialize(); 66 | connect(mLogger, &QOpenGLDebugLogger::messageLogged, this, [](const QOpenGLDebugMessage& msg) { qWarning() << msg.message(); }); 67 | mLogger->startLogging(); 68 | #endif 69 | 70 | glClearColor(0.2f, 0.3f, 0.4f, 1.0f); 71 | mMVPMat.setToIdentity(); 72 | mProgram = new QOpenGLShaderProgram(this); 73 | if (!mProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, sVertexShader)) 74 | { 75 | qWarning() << mProgram->log(); 76 | return; 77 | } 78 | if (!mProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, sFragmentShader)) 79 | { 80 | qWarning() << mProgram->log(); 81 | return; 82 | } 83 | if (!mProgram->link()) 84 | { 85 | qWarning() << mProgram->log(); 86 | return; 87 | } 88 | 89 | mVertices = { 90 | QVector3D { -0.0005f, -0.0005f, 1.0f }, 91 | QVector3D { -0.0005f, 0.0005f, 1.0f }, 92 | QVector3D { 0.0005f, 0.0005f, 1.0f }, 93 | QVector3D { 0.0005f, -0.0005f, 1.0f }, 94 | }; 95 | float offset = 0.001f; 96 | int w = 100; 97 | int h = 100; 98 | for (int i = -w; i < w; i += 2) 99 | { 100 | for (int j = -h; j < h; j += 2) 101 | { 102 | qreal px = 1.0f * i / w + offset; 103 | qreal py = 1.0f * j / h + offset; 104 | QMatrix4x4 mat; 105 | mat.translate(px, py); 106 | mInstanceMats.append(mat); 107 | } 108 | } 109 | 110 | { 111 | glGenBuffers(1, &mVerticesVBO); 112 | glGenBuffers(1, &mInstanceVBO); 113 | glGenVertexArrays(1, &mVAO); 114 | 115 | glBindBuffer(GL_ARRAY_BUFFER, mVerticesVBO); 116 | { 117 | glBufferData(GL_ARRAY_BUFFER, sizeof(QVector3D) * mVertices.size(), mVertices.constData(), GL_STATIC_DRAW); 118 | } 119 | glBindBuffer(GL_ARRAY_BUFFER, 0); 120 | 121 | glBindBuffer(GL_ARRAY_BUFFER, mInstanceVBO); 122 | { 123 | glBufferData(GL_ARRAY_BUFFER, sizeof(QMatrix4x4) * mInstanceMats.size(), mInstanceMats.constData(), GL_STATIC_DRAW); 124 | } 125 | glBindBuffer(GL_ARRAY_BUFFER, 0); 126 | 127 | const uint32_t vertexLocation = 0; 128 | const uint32_t instanceLocation1 = 1; 129 | const uint32_t instanceLocation2 = 2; 130 | const uint32_t instanceLocation3 = 3; 131 | const uint32_t instanceLocation4 = 4; 132 | glBindVertexArray(mVAO); 133 | { 134 | glEnableVertexAttribArray(vertexLocation); 135 | glBindBuffer(GL_ARRAY_BUFFER, mVerticesVBO); 136 | glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(QVector3D), (void*)0); 137 | 138 | glBindBuffer(GL_ARRAY_BUFFER, mInstanceVBO); 139 | 140 | glEnableVertexAttribArray(instanceLocation1); 141 | glVertexAttribPointer(instanceLocation1, 4, GL_FLOAT, GL_FALSE, sizeof(QMatrix4x4), (void*)0); 142 | 143 | glEnableVertexAttribArray(instanceLocation2); 144 | glVertexAttribPointer(instanceLocation2, 4, GL_FLOAT, GL_FALSE, sizeof(QMatrix4x4), (void*)(sizeof(QVector4D))); 145 | 146 | glEnableVertexAttribArray(instanceLocation3); 147 | glVertexAttribPointer(instanceLocation3, 4, GL_FLOAT, GL_FALSE, sizeof(QMatrix4x4), (void*)(2 * sizeof(QVector4D))); 148 | 149 | glEnableVertexAttribArray(instanceLocation4); 150 | glVertexAttribPointer(instanceLocation4, 4, GL_FLOAT, GL_FALSE, sizeof(QMatrix4x4), (void*)(3 * sizeof(QVector4D))); 151 | 152 | glBindBuffer(GL_ARRAY_BUFFER, 0); 153 | 154 | glVertexAttribDivisor(instanceLocation1, 1); 155 | glVertexAttribDivisor(instanceLocation2, 1); 156 | glVertexAttribDivisor(instanceLocation3, 1); 157 | glVertexAttribDivisor(instanceLocation4, 1); 158 | } 159 | glBindVertexArray(0); 160 | } 161 | startTimer(1000 / 60); 162 | } 163 | 164 | void MainWindow::resizeGL(int w, int h) 165 | { 166 | glViewport(0, 0, w, h); 167 | Super::resizeGL(w, h); 168 | } 169 | 170 | void MainWindow::paintGL() 171 | { 172 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 173 | glClearColor(0.2f, 0.3f, 0.4f, 1.0f); 174 | if (!mProgram->bind()) 175 | { 176 | qWarning() << mProgram->log(); 177 | return; 178 | } 179 | mProgram->setUniformValue("outColor0", mColor); 180 | mProgram->setUniformValue("mvpMatrix", mMVPMat); 181 | glBindVertexArray(mVAO); 182 | { 183 | glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, mInstanceMats.size()); 184 | } 185 | glBindVertexArray(0); 186 | calcFPS(); 187 | paintFPS(); 188 | } 189 | 190 | void MainWindow::timerEvent(QTimerEvent*) 191 | { 192 | if (isVisible()) 193 | { 194 | update(); 195 | } 196 | } 197 | 198 | void MainWindow::calcFPS() 199 | { 200 | static QTime time; 201 | static int once = [=]() { 202 | time.start(); 203 | return 0; 204 | }(); 205 | Q_UNUSED(once) 206 | static int frame = 0; 207 | if (frame++ > 100) 208 | { 209 | qreal elasped = time.elapsed(); 210 | updateFPS(frame / elasped * 1000); 211 | time.restart(); 212 | frame = 0; 213 | } 214 | } 215 | void MainWindow::updateFPS(qreal v) 216 | { 217 | mFPS = v; 218 | } 219 | void MainWindow::paintFPS() 220 | { 221 | setWindowTitle(QString("Instance 2 - FPS: %1").arg(QString::number(mFPS, 'f', 3))); 222 | } 223 | void MainWindow::initVertices() 224 | { 225 | // mCount = 2; 226 | // qreal x = 0.01; 227 | // qreal y = 0.01; 228 | // qreal w = 0.03; 229 | // qreal h = 0.02; 230 | // qreal xOffset = 0.01; 231 | // qreal yOffset = 0.01; 232 | // mVertices.clear(); 233 | // for (int i = 0; i < mCount; i++) 234 | // { 235 | // mVertices << QVector3D(x, y, 0.0); 236 | // mVertices << QVector3D(x + w, y, 0.0); 237 | // mVertices << QVector3D(x + w, y + h, 0.0); 238 | // mVertices << QVector3D(x, y + h, 0.0); 239 | // x += xOffset; 240 | // if (x + w >= 1.0) 241 | // { 242 | // x = 0.01; 243 | // y += yOffset; 244 | // } 245 | // } 246 | } 247 | 248 | void MainWindow::updateVertices() { } 249 | -------------------------------------------------------------------------------- /Instance2/mainWindow.h: -------------------------------------------------------------------------------- 1 | #include "qnamespace.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | class MainWindow 9 | : public QOpenGLWidget 10 | , public QOpenGLFunctions_3_3_Core 11 | { 12 | Q_OBJECT 13 | using Super = QOpenGLWidget; 14 | 15 | public: 16 | MainWindow(QWidget* parent = nullptr); 17 | ~MainWindow(); 18 | 19 | protected: 20 | virtual void initializeGL() override; 21 | virtual void resizeGL(int w, int h) override; 22 | virtual void paintGL() override; 23 | virtual void timerEvent(QTimerEvent* e) override; 24 | 25 | private: 26 | void initVertices(); 27 | void updateVertices(); 28 | 29 | void calcFPS(); 30 | void updateFPS(qreal); 31 | void paintFPS(); 32 | 33 | private: 34 | #ifdef _DEBUG 35 | QOpenGLDebugLogger* mLogger = nullptr; 36 | #endif 37 | QOpenGLShaderProgram* mProgram = nullptr; 38 | GLuint mVerticesVBO = 0; 39 | GLuint mInstanceVBO = 0; 40 | GLuint mVAO = 0; 41 | QColor mColor = Qt::red; 42 | QVector mVertices; 43 | QMatrix4x4 mMVPMat; 44 | QVector mInstanceMats; 45 | 46 | qreal mFPS = 60.0; 47 | }; 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 jared2020@163.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /QuickOpenGL/QuickOpenGL.pro: -------------------------------------------------------------------------------- 1 | QT += qml quick 2 | 3 | CONFIG += c++11 4 | 5 | 6 | 7 | # Additional import path used to resolve QML modules in Qt Creator's code model 8 | QML_IMPORT_PATH = 9 | 10 | 11 | RESOURCES += \ 12 | res/img.qrc \ 13 | res/qml.qrc \ 14 | res/shader.qrc 15 | 16 | HEADERS += \ 17 | src/shader.h 18 | 19 | SOURCES += \ 20 | src/main.cpp \ 21 | src/shader.cpp 22 | -------------------------------------------------------------------------------- /QuickOpenGL/deployment.pri: -------------------------------------------------------------------------------- 1 | unix:!android { 2 | isEmpty(target.path) { 3 | qnx { 4 | target.path = /tmp/$${TARGET}/bin 5 | } else { 6 | target.path = /opt/$${TARGET}/bin 7 | } 8 | export(target.path) 9 | } 10 | INSTALLS += target 11 | } 12 | 13 | export(INSTALLS) 14 | -------------------------------------------------------------------------------- /QuickOpenGL/res/img.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | img/s.jpg 4 | 5 | 6 | -------------------------------------------------------------------------------- /QuickOpenGL/res/img/s.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/QuickOpenGL/res/img/s.jpg -------------------------------------------------------------------------------- /QuickOpenGL/res/qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | qml/main.qml 4 | 5 | 6 | -------------------------------------------------------------------------------- /QuickOpenGL/res/qml/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.7 2 | import QtQuick.Controls 2.0 3 | import QtQuick.Layouts 1.0 4 | import Shader 1.0 5 | Item { 6 | id:root 7 | width: 800 8 | height: 600 9 | 10 | 11 | Shader { 12 | id:shader 13 | width: 400 14 | height:400 15 | x:200 16 | y:100 17 | // SequentialAnimation on x { 18 | // loops: Animation.Infinite 19 | // PropertyAnimation { to: 300 } 20 | // PropertyAnimation { to: 200 } 21 | // running:true 22 | // } 23 | states: [ 24 | State{ 25 | name:"TopLeft" 26 | PropertyChanges {target:shader; x:0; y:0;} 27 | }, 28 | State{ 29 | name:"TopRight" 30 | PropertyChanges {target:shader; x:400; y:0;} 31 | }, 32 | State{ 33 | name:"BottomLeft" 34 | PropertyChanges {target:shader; x:0; y:200;} 35 | }, 36 | State{ 37 | name:"BottomRight" 38 | PropertyChanges {target:shader; x:400; y:200;} 39 | }, 40 | State{ 41 | name:"Middle" 42 | PropertyChanges {target:shader; x:200; y:100;} 43 | } 44 | ] 45 | transitions: Transition { 46 | PropertyAnimation { duration: 750; properties: "x,y"; easing.type: Easing.InOutQuad } 47 | } 48 | state:"Middle" 49 | } 50 | Button { 51 | text:"TopLeft" 52 | anchors{top:parent.top; left:parent.left} 53 | onClicked: shader.state = "TopLeft" 54 | } 55 | Button { 56 | text:"TopRight" 57 | anchors{top:parent.top; right:parent.right} 58 | onClicked: shader.state = "TopRight" 59 | } 60 | Button { 61 | text:"BottomLeft" 62 | anchors{bottom:parent.bottom; left:parent.left} 63 | onClicked: shader.state = "BottomLeft" 64 | } 65 | Button { 66 | text:"BottomRight" 67 | anchors{bottom:parent.bottom; right:parent.right} 68 | onClicked: shader.state = "BottomRight" 69 | } 70 | Button { 71 | text:"middle" 72 | anchors.centerIn: parent 73 | onClicked: shader.state = "Middle" 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /QuickOpenGL/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fragment.fsh 4 | shader/vertex.vsh 5 | 6 | 7 | -------------------------------------------------------------------------------- /QuickOpenGL/res/shader/fragment.fsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision highp int; 4 | precision highp float; 5 | #endif 6 | uniform sampler2D qt_Texture0; 7 | varying highp vec4 qt_TexCoord0; 8 | varying vec4 v_Color; 9 | void main(void) 10 | { 11 | // gl_FragColor = v_Color; 12 | gl_FragColor = texture2D(qt_Texture0, qt_TexCoord0.st); 13 | } 14 | -------------------------------------------------------------------------------- /QuickOpenGL/res/shader/vertex.vsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision highp int; 4 | precision highp float; 5 | #endif 6 | attribute highp vec4 qt_Vertex; 7 | attribute highp vec4 qt_MultiTexCoord0; 8 | attribute vec4 a_Color; 9 | uniform highp mat4 qt_ModelViewProjectionMatrix; 10 | varying highp vec4 qt_TexCoord0; 11 | varying vec4 v_Color; 12 | void main(void) 13 | { 14 | v_Color = a_Color; 15 | gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; 16 | qt_TexCoord0 = qt_MultiTexCoord0; 17 | } 18 | -------------------------------------------------------------------------------- /QuickOpenGL/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "shader.h" 2 | #include 3 | #include 4 | #include 5 | int main(int argc, char* argv[]) 6 | { 7 | // QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 8 | qSetMessagePattern("log[%{file} %{function} %{line}] %{message}"); 9 | QGuiApplication app(argc, argv); 10 | 11 | qmlRegisterType("Shader", 1, 0, "Shader"); 12 | QQuickView view; 13 | view.setResizeMode(QQuickView::SizeRootObjectToView); 14 | view.setSource(QUrl(QLatin1Literal("qrc:/qml/main.qml"))); 15 | QObject::connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit())); 16 | view.show(); 17 | 18 | // QQmlApplicationEngine engine; 19 | // engine.load(QUrl(QLatin1String("qrc:/main.qml"))); 20 | 21 | return app.exec(); 22 | } 23 | -------------------------------------------------------------------------------- /QuickOpenGL/src/shader.h: -------------------------------------------------------------------------------- 1 | #ifndef SHADER_H 2 | #define SHADER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | class Render 15 | : public QObject 16 | , protected QOpenGLFunctions 17 | { 18 | Q_OBJECT 19 | public: 20 | Render(QRect rect); 21 | ~Render(); 22 | void setWindow(QQuickWindow* window); 23 | 24 | void init(); 25 | void resize(); 26 | public slots: 27 | void paint(); 28 | void setGemo(QRect); 29 | 30 | private: 31 | void initShaders(); 32 | void initTextures(); 33 | 34 | void initData(); 35 | void draw(); 36 | 37 | void calcFPS(); 38 | void updateFPS(qreal); 39 | void paintFPS(); 40 | 41 | QRect m_gemo; 42 | QSize m_viewportSize; 43 | 44 | QOpenGLShaderProgram m_program; 45 | QQuickWindow* m_window; 46 | 47 | QOpenGLTexture* texture; 48 | 49 | QVector vertices; 50 | QVector colors; 51 | QVector texcoords; 52 | int mMVPMatrixHandle; 53 | int mVerticesHandle; 54 | int mColorsHandle; 55 | int mTexCoordHandle; 56 | 57 | QMatrix4x4 mModelMatrix; 58 | QMatrix4x4 mViewMatrix; 59 | QMatrix4x4 mProjectionMatrix; 60 | QMatrix4x4 mMVPMatrix; 61 | QTimer* timer; 62 | qreal angleInDegrees; 63 | qreal fps; 64 | bool isInited; 65 | }; 66 | class Line : public QQuickPaintedItem 67 | { 68 | protected: 69 | void paint(QPainter* painter); 70 | }; 71 | class Shader : public QQuickItem 72 | { 73 | Q_OBJECT 74 | public: 75 | Shader(QQuickItem* parent = 0); 76 | 77 | protected: 78 | void timerEvent(QTimerEvent* event); 79 | 80 | signals: 81 | void sizeChanged(QRect); 82 | public slots: 83 | void sync(); 84 | void cleanup(); 85 | void recalcSize(); 86 | private slots: 87 | void handleWindowChanged(QQuickWindow* win); 88 | 89 | private: 90 | Render* m_render; 91 | Line* line; 92 | }; 93 | 94 | #endif // SHADER_H 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qt5 OpenGL 2 | 3 | Qt5写的一些OpenGL小例子集合, 4 | 参考[LearnOpenGL教程](http://bullteacher.com/category/zh_learnopengl_com) 5 | 6 | 7 | - [Qt5 OpenGL](#qt5-opengl) 8 | - [CI徽章](#ci%e5%be%bd%e7%ab%a0) 9 | - [工程列表](#%e5%b7%a5%e7%a8%8b%e5%88%97%e8%a1%a8) 10 | - [HelloTexture](#hellotexture) 11 | - [HelloCube](#hellocube) 12 | - [HelloMix](#hellomix) 13 | - [QuickOpenGL](#quickopengl) 14 | - [FrameBufferObject](#framebufferobject) 15 | - [light](#light) 16 | - [lightCasters](#lightcasters) 17 | - [mulitLight](#mulitlight) 18 | - [material](#material) 19 | - [DepthTest](#depthtest) 20 | - [SkyBox](#skybox) 21 | - [HelloFBO](#hellofbo) 22 | - [赞助](#%e8%b5%9e%e5%8a%a9) 23 | - [联系作者](#%e8%81%94%e7%b3%bb%e4%bd%9c%e8%80%85) 24 | 25 | # CI徽章 26 | 27 | |[License][license-link]| [Windows][win-link]|[MacOS][macos-link]| [Ubuntu][ubuntu-link]|[Android][android-link]|[IOS][ios-link]| 28 | |---------------|---------------|---------------|-----------------|-----------------|----------------| 29 | |![license-badge] | ![win-badge] |![macos-badge] | ![ubuntu-badge] | ![android-badge] |![ios-badge] | 30 | 31 | 32 | 33 | [win-link]: https://github.com/JaredTao/QtOpenGL/actions?query=workflow%3AWindows "WindowsAction" 34 | [win-badge]: https://github.com/JaredTao/QtOpenGL/workflows/Windows/badge.svg "Windows" 35 | 36 | [ubuntu-link]: https://github.com/JaredTao/QtOpenGL/actions?query=workflow%3AUbuntu "UbuntuAction" 37 | [ubuntu-badge]: https://github.com/JaredTao/QtOpenGL/workflows/Ubuntu/badge.svg "Ubuntu" 38 | 39 | [macos-link]: https://github.com/JaredTao/QtOpenGL/actions?query=workflow%3AMacOS "MacOSAction" 40 | [macos-badge]: https://github.com/JaredTao/QtOpenGL/workflows/MacOS/badge.svg "MacOS" 41 | 42 | [android-link]: https://github.com/JaredTao/QtOpenGL/actions?query=workflow%3AAndroid "AndroidAction" 43 | [android-badge]: https://github.com/JaredTao/QtOpenGL/workflows/Android/badge.svg "Android" 44 | 45 | [ios-link]: https://github.com/JaredTao/QtOpenGL/actions?query=workflow%3AIOS "IOSAction" 46 | [ios-badge]: https://github.com/JaredTao/QtOpenGL/workflows/IOS/badge.svg "IOS" 47 | 48 | [license-link]: https://github.com/jaredtao/QtOpenGL/blob/master/LICENSE "LICENSE" 49 | [license-badge]: https://img.shields.io/badge/license-MIT-blue.svg "MIT" 50 | 51 | # 工程列表 52 | 53 | ## HelloTexture 54 | 55 | 以QOpenGLWidget为框架,简单的纹理贴图,使用定时器控制纹理旋转。 56 | ![HelloTexture](img/HelloTexture.png) 57 | 58 | ## HelloCube 59 | 60 | 立方体贴图的例子,自己用画板画了一个图,然后贴成一个Cube。可以用鼠标控制立方体旋转。 61 | 62 | ![HelloCube](img/HelloCube.png) 63 | 64 | ## HelloMix 65 | 66 | 绘制了10个立方体,每个立方体的每个表面使用2张纹理混合贴图。混合比例按数字键1/2进行调节。 67 | 68 | ![HelloMix](img/HelloMix.png) 69 | 70 | ## QuickOpenGL 71 | 72 | qml中添加自定义OpenGL渲染控件。 73 | 74 | ![QuickOpenGL](img/QuickOpenGL.png) 75 | 76 | 用的是QQuickWindow的beforeRendering信号。 77 | 78 | 知道了QQuickFramebufferObject之后,基本上这种方式就被抛弃了。(默认渲染区域是整个window,要自己控制viewport。来自Qml的旋转、平移、缩放也要自己做支持。不方便。) 79 | 80 | 这里保留项目仅作为观赏,建议参考下面FrameBufferObject。 81 | 82 | ## FrameBufferObject 83 | 84 | 效果与上一个例子QuickOpenGL 类似,多了全屏放大功能,纹理沿着三个坐标轴旋转的功能。 85 | 86 | ![FrameBufferObject](img/FrameBufferObject.png) 87 | 88 | 使用QQuickFramebufferObject 作为OpenGL自绘制控件(相当于QQuickItem了)。 89 | 90 | QQuickFramebufferObject是 Qt封装好的,需要理解其使用架构。 91 | 92 | 这里大概说一下用法: 93 | 94 | 1. 继承QQuickFramebufferObject实现一个自定义item,并注册到QML中使用。Item在Qml中的旋转、平移、缩放都能支持。 95 | 2. 继承QQuickFramebufferObject::Renderer,实现一个自定义Renderer 96 | 3. 自定义Renderer内部再封装一个OpenGL相关的渲染类。Renderer是在Scene Graph线程工作,始终拥有OpenGL上下文环境,所以渲染类写在Renderer内部,非常方便。 97 | (Item工作在主线程,Renderer 工作在Scene Graph绘图线程。注意线程交互) 98 | 99 | ## light 100 | 101 | Shader光照的例子。 一个立方体的前面, 放一个移动的光源。 102 | 103 | ![light](img/light.png) 104 | ## lightCasters 105 | 106 | 手电筒光源 107 | 108 | ![lightCasters](img/lightCasters.png) 109 | 110 | ## mulitLight 111 | 112 | 镜面反射、漫反射,手电筒的集合 113 | ![mulitLight](img/mulitLight.png) 114 | 115 | ## material 116 | 117 | 材质的使用,边缘部分发光,中间部分不发光 118 | 119 | ![material](img/material.png) 120 | 121 | ## DepthTest 122 | 123 | 利用深度测试,后面的箱子边缘部分用红色绘制出来 124 | 125 | ![DepthTest](img/DepthTest.png) 126 | 127 | ## SkyBox 128 | 129 | 天空盒, 可以键盘和鼠标操作 130 | 131 | ![SkyBox](img/SkyBox.png) 132 | 133 | ## HelloFBO 134 | 135 | 帧缓冲的使用 136 | 137 | 反相处理效果如下: 138 | 139 | ![HelloFBO](img/HelloFBO.png) 140 | 141 | # 赞助 142 | 143 | 如果您觉得这个项目还不错,请打赏一下作者。 144 | 145 | 146 | 147 | # 联系作者 148 | 149 | |-|-| 150 | | ---- | -------------------------------- | 151 | | 作者 | 武威的涛哥 | 152 | | 博客 | https://jaredtao.github.io/ | 153 | | 博客-gitee镜像|https://jaredtao.gitee.io| 154 | | 知乎专栏| https://zhuanlan.zhihu.com/TaoQt | 155 | | QQ群| 734623697(高质量群,大佬多、不灌水)| 156 | | 邮箱 | jared2020@163.com | 157 | | 微信 | xsd2410421 | 158 | | QQ、TIM | 759378563 | 159 | -------------------------------------------------------------------------------- /SkyBox/Assets.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | assets/cube.png 4 | assets/back.jpg 5 | assets/bottom.jpg 6 | assets/front.jpg 7 | assets/left.jpg 8 | assets/right.jpg 9 | assets/top.jpg 10 | 11 | 12 | -------------------------------------------------------------------------------- /SkyBox/SkyBox.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | CONFIG += c++11 3 | 4 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 5 | 6 | TEMPLATE = app 7 | 8 | SOURCES += \ 9 | src/Cube.cpp \ 10 | src/SkyBox.cpp \ 11 | src/TWindow.cpp \ 12 | src/main.cpp 13 | 14 | HEADERS += \ 15 | src/Cube.h \ 16 | src/GLHeaders.h \ 17 | src/SkyBox.h \ 18 | src/TWindow.h 19 | 20 | RESOURCES += \ 21 | Assets.qrc 22 | -------------------------------------------------------------------------------- /SkyBox/assets/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/SkyBox/assets/back.jpg -------------------------------------------------------------------------------- /SkyBox/assets/bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/SkyBox/assets/bottom.jpg -------------------------------------------------------------------------------- /SkyBox/assets/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/SkyBox/assets/cube.png -------------------------------------------------------------------------------- /SkyBox/assets/front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/SkyBox/assets/front.jpg -------------------------------------------------------------------------------- /SkyBox/assets/left.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/SkyBox/assets/left.jpg -------------------------------------------------------------------------------- /SkyBox/assets/right.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/SkyBox/assets/right.jpg -------------------------------------------------------------------------------- /SkyBox/assets/top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/SkyBox/assets/top.jpg -------------------------------------------------------------------------------- /SkyBox/src/Cube.cpp: -------------------------------------------------------------------------------- 1 | #include "Cube.h" 2 | #include 3 | #include 4 | #include 5 | struct VertexData 6 | { 7 | QVector3D position; 8 | QVector2D texCoord; 9 | }; 10 | Cube::Cube(GLFuncName* func) 11 | : m_func(func) 12 | , m_indexBuf(QOpenGLBuffer::IndexBuffer) 13 | , m_vertexShader(QOpenGLShader::Vertex) 14 | , m_fragmentShader(QOpenGLShader::Fragment) 15 | , m_texture(QOpenGLTexture::Target2D) 16 | { 17 | initBuffer(); 18 | initShader(); 19 | initTexture(); 20 | } 21 | Cube::~Cube() 22 | { 23 | m_arrayBuf.destroy(); 24 | m_indexBuf.destroy(); 25 | m_texture.destroy(); 26 | } 27 | void Cube::initBuffer() 28 | { 29 | m_arrayBuf.create(); 30 | m_indexBuf.create(); 31 | 32 | VertexData vertices[] = { 33 | // Vertex data for face 0 34 | { QVector3D(-0.5f, -0.5f, 0.5f), QVector2D(0.0f, 0.0f) }, // v0 35 | { QVector3D(0.5f, -0.5f, 0.5f), QVector2D(0.33f, 0.0f) }, // v1 36 | { QVector3D(-0.5f, 0.5f, 0.5f), QVector2D(0.0f, 0.5f) }, // v2 37 | { QVector3D(0.5f, 0.5f, 0.5f), QVector2D(0.33f, 0.5f) }, // v3 38 | 39 | // Vertex data for face 1 40 | { QVector3D(0.5f, -0.5f, 0.5f), QVector2D(0.0f, 0.5f) }, // v4 41 | { QVector3D(0.5f, -0.5f, -0.5f), QVector2D(0.33f, 0.5f) }, // v5 42 | { QVector3D(0.5f, 0.5f, 0.5f), QVector2D(0.0f, 1.0f) }, // v6 43 | { QVector3D(0.5f, 0.5f, -0.5f), QVector2D(0.33f, 1.0f) }, // v7 44 | 45 | // Vertex data for face 2 46 | { QVector3D(0.5f, -0.5f, -0.5f), QVector2D(0.66f, 0.5f) }, // v8 47 | { QVector3D(-0.5f, -0.5f, -0.5f), QVector2D(1.0f, 0.5f) }, // v9 48 | { QVector3D(0.5f, 0.5f, -0.5f), QVector2D(0.66f, 1.0f) }, // v10 49 | { QVector3D(-0.5f, 0.5f, -0.5f), QVector2D(1.0f, 1.0f) }, // v11 50 | 51 | // Vertex data for face 3 52 | { QVector3D(-0.5f, -0.5f, -0.5f), QVector2D(0.66f, 0.0f) }, // v12 53 | { QVector3D(-0.5f, -0.5f, 0.5f), QVector2D(1.0f, 0.0f) }, // v13 54 | { QVector3D(-0.5f, 0.5f, -0.5f), QVector2D(0.66f, 0.5f) }, // v14 55 | { QVector3D(-0.5f, 0.5f, 0.5f), QVector2D(1.0f, 0.5f) }, // v15 56 | 57 | // Vertex data for face 4 58 | { QVector3D(-0.5f, -0.5f, -0.5f), QVector2D(0.33f, 0.0f) }, // v16 59 | { QVector3D(0.5f, -0.5f, -0.5f), QVector2D(0.66f, 0.0f) }, // v17 60 | { QVector3D(-0.5f, -0.5f, 0.5f), QVector2D(0.33f, 0.5f) }, // v18 61 | { QVector3D(0.5f, -0.5f, 0.5f), QVector2D(0.66f, 0.5f) }, // v19 62 | 63 | // Vertex data for face 5 64 | { QVector3D(-0.5f, 0.5f, 0.5f), QVector2D(0.33f, 0.5f) }, // v20 65 | { QVector3D(0.5f, 0.5f, 0.5f), QVector2D(0.66f, 0.5f) }, // v21 66 | { QVector3D(-0.5f, 0.5f, -0.5f), QVector2D(0.33f, 1.0f) }, // v22 67 | { QVector3D(0.5f, 0.5f, -0.5f), QVector2D(0.66f, 1.0f) } // v23 68 | }; 69 | // Indices for drawing cube faces using triangle strips. 70 | // Triangle strips can be connected by duplicating indices 71 | // between the strips. If connecting strips have opposite 72 | // vertex order then last index of the first strip and first 73 | // index of the second strip needs to be duplicated. If 74 | // connecting strips have same vertex order then only last 75 | // index of the first strip needs to be duplicated. 76 | GLushort indices[] = { 77 | 0, 1, 2, 3, 3, // Face 0 - triangle strip ( v0, v1, v2, v3) 78 | 4, 4, 5, 6, 7, 7, // Face 1 - triangle strip ( v4, v5, v6, v7) 79 | 8, 8, 9, 10, 11, 11, // Face 2 - triangle strip ( v8, v9, v10, v11) 80 | 12, 12, 13, 14, 15, 15, // Face 3 - triangle strip (v12, v13, v14, v15) 81 | 16, 16, 17, 18, 19, 19, // Face 4 - triangle strip (v16, v17, v18, v19) 82 | 20, 20, 21, 22, 23 // Face 5 - triangle strip (v20, v21, v22, v23) 83 | }; 84 | m_indexCount = sizeof indices / sizeof(indices[0]); 85 | 86 | m_func->glGenVertexArrays(1, &m_vao); 87 | m_func->glBindVertexArray(m_vao); 88 | 89 | m_indexBuf.bind(); 90 | m_indexBuf.allocate(indices, sizeof indices); 91 | 92 | m_arrayBuf.bind(); 93 | m_arrayBuf.allocate(vertices, sizeof vertices); 94 | 95 | const int positionLocation = 0; 96 | m_func->glEnableVertexAttribArray(positionLocation); 97 | m_func->glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), nullptr); 98 | 99 | const int texCoordLocation = 1; 100 | m_func->glEnableVertexAttribArray(texCoordLocation); 101 | m_func->glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(QVector3D))); 102 | 103 | m_func->glBindVertexArray(0); 104 | } 105 | 106 | void Cube::initShader() 107 | { 108 | const auto vShader = u8R"(#version 330 core 109 | layout(location = 0) in vec3 position; 110 | layout(location = 1) in vec2 texCoord; 111 | uniform mat4 mvp; 112 | out vec2 vTexCoord; 113 | void main() 114 | { 115 | vTexCoord = texCoord; 116 | gl_Position = mvp * vec4(position, 1.0); 117 | } 118 | )"; 119 | const auto fShader = R"(#version 330 core 120 | uniform sampler2D cubeTexture; 121 | in vec2 vTexCoord; 122 | out vec4 outColor; 123 | void main() 124 | { 125 | outColor = texture(cubeTexture, vTexCoord); 126 | } 127 | )"; 128 | if (!m_vertexShader.compileSourceCode(vShader)) 129 | { 130 | qWarning() << m_vertexShader.log(); 131 | } 132 | if (!m_fragmentShader.compileSourceCode(fShader)) 133 | { 134 | qWarning() << m_fragmentShader.log(); 135 | } 136 | } 137 | void Cube::initTexture() 138 | { 139 | QImage img(":/assets/cube.png"); 140 | m_texture.setData(img.mirrored()); 141 | m_texture.setMinificationFilter(QOpenGLTexture::Nearest); 142 | m_texture.setMagnificationFilter(QOpenGLTexture::Linear); 143 | m_texture.setWrapMode(QOpenGLTexture::Repeat); 144 | } 145 | void Cube::draw(QOpenGLShaderProgram& program, const QMatrix4x4& model, const QMatrix4x4& view, const QMatrix4x4& project) 146 | { 147 | program.removeAllShaders(); 148 | program.addShader(&m_vertexShader); 149 | program.addShader(&m_fragmentShader); 150 | if (!program.link()) 151 | { 152 | qWarning() << program.log(); 153 | return; 154 | } 155 | if (!program.bind()) 156 | { 157 | qWarning() << program.log(); 158 | return; 159 | } 160 | program.setUniformValue("mvp", project * view * model); 161 | 162 | m_texture.bind(); 163 | program.setUniformValue("cubeTexture", 0); 164 | 165 | m_func->glBindVertexArray(m_vao); 166 | 167 | m_func->glDrawElements(GL_TRIANGLE_STRIP, m_indexCount, GL_UNSIGNED_SHORT, nullptr); 168 | } 169 | -------------------------------------------------------------------------------- /SkyBox/src/Cube.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GLHeaders.h" 3 | 4 | class Cube 5 | { 6 | public: 7 | Cube(GLFuncName* func); 8 | ~Cube(); 9 | void draw(QOpenGLShaderProgram& program, const QMatrix4x4& model, const QMatrix4x4& view, const QMatrix4x4& project); 10 | 11 | private: 12 | void initBuffer(); 13 | void initShader(); 14 | void initTexture(); 15 | 16 | private: 17 | GLFuncName* m_func; 18 | QOpenGLBuffer m_arrayBuf; 19 | QOpenGLBuffer m_indexBuf; 20 | QOpenGLShader m_vertexShader; 21 | QOpenGLShader m_fragmentShader; 22 | QOpenGLTexture m_texture; 23 | quint32 m_vao; 24 | int m_indexCount = 0; 25 | }; 26 | -------------------------------------------------------------------------------- /SkyBox/src/GLHeaders.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #ifdef _DEBUG 9 | #include 10 | #endif 11 | 12 | #define GLFuncName QOpenGLExtraFunctions 13 | -------------------------------------------------------------------------------- /SkyBox/src/SkyBox.cpp: -------------------------------------------------------------------------------- 1 | #include "SkyBox.h" 2 | 3 | SkyBox::SkyBox(GLFuncName* func) 4 | : m_func(func) 5 | , m_vertexShader(QOpenGLShader::Vertex) 6 | , m_fragmentShader(QOpenGLShader::Fragment) 7 | { 8 | initBuffer(); 9 | initShader(); 10 | initTexture(); 11 | } 12 | 13 | SkyBox::~SkyBox() 14 | { 15 | m_arrayBuf.destroy(); 16 | } 17 | 18 | void SkyBox::initBuffer() 19 | { 20 | GLfloat skyboxVertices[] = { // Positions 21 | -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 22 | 23 | -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 24 | 25 | 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 26 | 27 | -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 28 | 29 | -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 30 | 31 | -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f 32 | }; 33 | m_vertexCount = sizeof skyboxVertices / sizeof skyboxVertices[0]; 34 | m_arrayBuf.create(); 35 | 36 | m_func->glGenVertexArrays(1, &m_vao); 37 | m_func->glBindVertexArray(m_vao); 38 | 39 | m_arrayBuf.bind(); 40 | m_arrayBuf.allocate(skyboxVertices, sizeof skyboxVertices); 41 | const int positionLocation = 0; 42 | m_func->glEnableVertexAttribArray(positionLocation); 43 | m_func->glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, nullptr); 44 | 45 | m_func->glBindVertexArray(0); 46 | } 47 | 48 | void SkyBox::initShader() 49 | { 50 | const auto vShader = u8R"(#version 330 core 51 | layout(location = 0) in vec3 position; 52 | uniform mat4 mvp; 53 | out vec3 vTexCoord; 54 | void main() 55 | { 56 | vTexCoord = position; 57 | vec4 pos = mvp * vec4(position, 1.0); 58 | gl_Position = pos.xyww; 59 | } 60 | )"; 61 | const auto fShader = R"(#version 330 core 62 | uniform samplerCube skyBox; 63 | in vec3 vTexCoord; 64 | out vec4 outColor; 65 | void main() 66 | { 67 | outColor = texture(skyBox, vTexCoord); 68 | } 69 | )"; 70 | if (!m_vertexShader.compileSourceCode(vShader)) 71 | { 72 | qWarning() << m_vertexShader.log(); 73 | } 74 | if (!m_fragmentShader.compileSourceCode(fShader)) 75 | { 76 | qWarning() << m_fragmentShader.log(); 77 | } 78 | } 79 | 80 | void SkyBox::initTexture() 81 | { 82 | m_images[0] = QImage(":/assets/right.jpg").convertToFormat(QImage::Format_RGB888); 83 | m_images[1] = QImage(":/assets/left.jpg").convertToFormat(QImage::Format_RGB888); 84 | m_images[2] = QImage(":/assets/top.jpg").convertToFormat(QImage::Format_RGB888); 85 | m_images[3] = QImage(":/assets/bottom.jpg").convertToFormat(QImage::Format_RGB888); 86 | m_images[4] = QImage(":/assets/back.jpg").convertToFormat(QImage::Format_RGB888); 87 | m_images[5] = QImage(":/assets/front.jpg").convertToFormat(QImage::Format_RGB888); 88 | m_func->glGenTextures(1, &m_cubeTexture); 89 | m_func->glBindTexture(GL_TEXTURE_CUBE_MAP, m_cubeTexture); 90 | for (unsigned int i = 0; i < 6; ++i) 91 | { 92 | m_func->glTexImage2D( 93 | GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, m_images[i].width(), m_images[i].height(), 0, GL_RGB, GL_UNSIGNED_BYTE, m_images[i].bits()); 94 | } 95 | m_func->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 96 | m_func->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 97 | m_func->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 98 | m_func->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 99 | m_func->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 100 | // m_texture.create(); 101 | // m_texture.setMinMagFilters(QOpenGLTexture::Nearest, QOpenGLTexture::Nearest); 102 | // m_texture.setWrapMode(QOpenGLTexture::ClampToEdge); 103 | // m_texture.setMipLevels(0); 104 | // m_texture.setLayers(0); 105 | // m_texture.setSize(m_images[0].width(), m_images[0].height(), m_images[0].depth()); 106 | // m_texture.setFormat(QOpenGLTexture::RGB8_UNorm); 107 | // m_texture.allocateStorage(QOpenGLTexture::RGB, QOpenGLTexture::UInt8); 108 | // for (int i = 0; i < 6; ++i) { 109 | // m_texture.setData(0, 0, static_cast(QOpenGLTexture::CubeMapPositiveX + i), QOpenGLTexture::RGB, 110 | // QOpenGLTexture::UInt8, m_images[i].bits()); 111 | // } 112 | // m_texture.generateMipMaps(); 113 | } 114 | void SkyBox::draw(QOpenGLShaderProgram& program, const QMatrix4x4& model, const QMatrix4x4& view, const QMatrix4x4& project) 115 | { 116 | m_func->glDepthFunc(GL_LEQUAL); 117 | program.removeAllShaders(); 118 | program.addShader(&m_vertexShader); 119 | program.addShader(&m_fragmentShader); 120 | if (!program.link()) 121 | { 122 | qWarning() << program.log(); 123 | return; 124 | } 125 | if (!program.bind()) 126 | { 127 | qWarning() << program.log(); 128 | return; 129 | } 130 | m_func->glBindVertexArray(m_vao); 131 | 132 | m_func->glActiveTexture(GL_TEXTURE0); 133 | m_func->glBindTexture(GL_TEXTURE_CUBE_MAP, m_cubeTexture); 134 | program.setUniformValue("mvp", project * view * model); 135 | program.setUniformValue("skyBox", 0); 136 | 137 | m_func->glDrawArrays(GL_TRIANGLES, 0, m_vertexCount); 138 | 139 | m_func->glDepthFunc(GL_LESS); 140 | } 141 | -------------------------------------------------------------------------------- /SkyBox/src/SkyBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "GLHeaders.h" 3 | 4 | class SkyBox 5 | { 6 | public: 7 | SkyBox(GLFuncName* func); 8 | ~SkyBox(); 9 | void draw(QOpenGLShaderProgram& program, const QMatrix4x4& model, const QMatrix4x4& view, const QMatrix4x4& project); 10 | 11 | private: 12 | void initBuffer(); 13 | void initShader(); 14 | void initTexture(); 15 | 16 | private: 17 | GLFuncName* m_func; 18 | QOpenGLBuffer m_arrayBuf; 19 | QOpenGLShader m_vertexShader; 20 | QOpenGLShader m_fragmentShader; 21 | QImage m_images[6]; 22 | quint32 m_cubeTexture; 23 | quint32 m_vao; 24 | int m_vertexCount = 0; 25 | }; 26 | -------------------------------------------------------------------------------- /SkyBox/src/TWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "TWindow.h" 2 | #include 3 | #include 4 | #include 5 | TWindow::TWindow() 6 | { 7 | resize(800, 600); 8 | } 9 | 10 | TWindow::~TWindow() 11 | { 12 | makeCurrent(); 13 | m_cube = nullptr; 14 | m_skyBox = nullptr; 15 | #ifdef _DEBUG 16 | m_logger.stopLogging(); 17 | #endif 18 | doneCurrent(); 19 | } 20 | 21 | void TWindow::initializeGL() 22 | { 23 | initializeOpenGLFunctions(); 24 | 25 | #ifdef _DEBUG 26 | bool ok = m_logger.initialize(); 27 | connect(&m_logger, &QOpenGLDebugLogger::messageLogged, [](const QOpenGLDebugMessage& debugMessage) { qWarning() << debugMessage.message(); }); 28 | m_logger.startLogging(); 29 | qWarning() << "debugger init " << ok; 30 | #endif 31 | 32 | glClearColor(0.1f, 0.2f, 0.3f, 1.0f); 33 | glEnable(GL_CULL_FACE); 34 | glEnable(GL_DEPTH_TEST); 35 | initMatrix(); 36 | 37 | m_cube = std::make_shared(this); 38 | m_skyBox = std::make_shared(this); 39 | startTimer(1000 / 60); 40 | } 41 | 42 | void TWindow::resizeGL(int w, int h) 43 | { 44 | glViewport(0, 0, w, h); 45 | float ratio = float(w) / (h ? h : 1); 46 | m_project.setToIdentity(); 47 | m_project.perspective(m_aspect, ratio, c_near, c_far); 48 | } 49 | 50 | void TWindow::paintGL() 51 | { 52 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 53 | checkKey(); 54 | m_view.setToIdentity(); 55 | m_view.lookAt(m_cameraPos, m_cameraPos + m_cameraFront, m_cameraUp); 56 | m_project.setToIdentity(); 57 | m_project.perspective(m_aspect, width() / height(), c_near, c_far); 58 | QMatrix4x4 matrix; 59 | matrix.translate(0.0, 0.0, -5.0); 60 | matrix.rotate(m_rotation); 61 | m_model = matrix; 62 | m_cube->draw(m_program, m_model, m_view, m_project); 63 | m_skyBox->draw(m_program, {}, QMatrix4x4(m_view.normalMatrix()), m_project); 64 | } 65 | 66 | void TWindow::timerEvent(QTimerEvent*) 67 | { 68 | m_angularSpeed *= 0.99f; 69 | if (m_angularSpeed <= 0.01f) 70 | { 71 | m_angularSpeed = 0; 72 | } 73 | else 74 | { 75 | m_rotation = QQuaternion::fromAxisAndAngle(m_rotationAxis, m_angularSpeed) * m_rotation; 76 | update(); 77 | } 78 | // update(); 79 | } 80 | 81 | void TWindow::mousePressEvent(QMouseEvent* event) 82 | { 83 | m_last = event->pos(); 84 | m_mousePressPosition = QVector2D { event->localPos() }; 85 | } 86 | 87 | void TWindow::mouseMoveEvent(QMouseEvent* event) 88 | { 89 | QPointF diff = event->pos() - m_last; 90 | m_last = event->pos(); 91 | 92 | qreal sensitivity = 0.05; 93 | qreal xOffset = diff.x() * sensitivity; 94 | qreal yOffset = diff.y() * sensitivity; 95 | m_yaw += xOffset; 96 | m_pitch += yOffset; 97 | if (m_pitch > 89.0) 98 | { 99 | m_pitch = 89.0; 100 | } 101 | else if (m_pitch < -89.0) 102 | { 103 | m_pitch = -89.0; 104 | } 105 | QVector3D front; 106 | front.setX(cos(qDegreesToRadians(m_pitch)) * cos(qDegreesToRadians(m_yaw))); 107 | front.setY(sin(qDegreesToRadians(m_pitch))); 108 | front.setZ(cos(qDegreesToRadians(m_pitch)) * sin(qDegreesToRadians(m_yaw))); 109 | m_cameraFront = front.normalized(); 110 | 111 | event->accept(); 112 | } 113 | void TWindow::wheelEvent(QWheelEvent* event) 114 | { 115 | int offset = event->angleDelta().y() < 0 ? -1 : 1; 116 | qreal speed = 10; 117 | if (1 <= m_aspect + offset * speed && m_aspect + offset * speed <= 45) 118 | { 119 | m_aspect = m_aspect + offset * speed; 120 | } 121 | event->accept(); 122 | } 123 | 124 | void TWindow::mouseReleaseEvent(QMouseEvent* event) 125 | { 126 | QVector2D diff = QVector2D { event->localPos() } - m_mousePressPosition; 127 | QVector3D n = QVector3D(diff.y(), diff.x(), 0.0).normalized(); 128 | 129 | float acc = diff.length() / 100.0f; 130 | m_rotationAxis = (m_rotationAxis * m_angularSpeed + n * acc).normalized(); 131 | 132 | m_angularSpeed += acc; 133 | } 134 | 135 | void TWindow::keyPressEvent(QKeyEvent* event) 136 | { 137 | if (0 <= event->key() && event->key() < (int)(sizeof(m_keys) / sizeof(m_keys[0]))) 138 | { 139 | m_keys[event->key()] = true; 140 | } 141 | if (event->key() == Qt::Key_F5) 142 | { 143 | m_model.setToIdentity(); 144 | m_view.setToIdentity(); 145 | m_project.setToIdentity(); 146 | 147 | m_cameraPos = QVector3D(0.0f, 0.0f, 3.0f); 148 | m_cameraFront = QVector3D(0.0f, 0.0f, -1.0f); 149 | m_cameraUp = QVector3D(0.0f, 1.0f, 0.0f); 150 | m_elapsed = 100; 151 | m_yaw = -90; 152 | m_pitch = 0; 153 | m_aspect = 45; 154 | update(); 155 | } 156 | event->accept(); 157 | } 158 | 159 | void TWindow::keyReleaseEvent(QKeyEvent* event) 160 | { 161 | if (0 <= event->key() && event->key() < (int)(sizeof(m_keys) / sizeof(m_keys[0]))) 162 | { 163 | m_keys[event->key()] = false; 164 | } 165 | event->accept(); 166 | } 167 | 168 | void TWindow::initMatrix() 169 | { 170 | m_model.setToIdentity(); 171 | m_view.setToIdentity(); 172 | m_view.lookAt({ 0, 0, 3.0 }, { 0, 0, 0 }, { 0, 1, 0 }); 173 | 174 | float ratio = float(width()) / (height() ? height() : 1); 175 | 176 | m_project.setToIdentity(); 177 | m_project.perspective(m_aspect, ratio, c_near, c_far); 178 | } 179 | 180 | void TWindow::checkKey() 181 | { 182 | GLfloat cameraSpeed = 0.05 * m_elapsed / 1000.0; 183 | if (m_keys[Qt::Key_A]) 184 | { 185 | m_cameraPos -= QVector3D::crossProduct(m_cameraFront, m_cameraUp).normalized() * cameraSpeed; 186 | qDebug() << "key a, left"; 187 | update(); 188 | } 189 | if (m_keys[Qt::Key_D]) 190 | { 191 | m_cameraPos += QVector3D::crossProduct(m_cameraFront, m_cameraUp).normalized() * cameraSpeed; 192 | qDebug() << "key d, right"; 193 | update(); 194 | } 195 | if (m_keys[Qt::Key_W]) 196 | { 197 | m_cameraPos += cameraSpeed * m_cameraFront; 198 | qDebug() << "key w, front"; 199 | update(); 200 | } 201 | if (m_keys[Qt::Key_S]) 202 | { 203 | m_cameraPos -= cameraSpeed * m_cameraFront; 204 | qDebug() << "key s, back"; 205 | update(); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /SkyBox/src/TWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Cube.h" 4 | #include "GLHeaders.h" 5 | #include "SkyBox.h" 6 | #include 7 | #include 8 | #include 9 | class TWindow 10 | : public QOpenGLWidget 11 | , public GLFuncName 12 | { 13 | public: 14 | TWindow(); 15 | ~TWindow() override; 16 | 17 | protected: 18 | void initializeGL() override; 19 | void resizeGL(int w, int h) override; 20 | void paintGL() override; 21 | void timerEvent(QTimerEvent*) override; 22 | void mousePressEvent(QMouseEvent* event) override; 23 | void mouseMoveEvent(QMouseEvent* event) override; 24 | void mouseReleaseEvent(QMouseEvent* event) override; 25 | void keyPressEvent(QKeyEvent* event) override; 26 | void keyReleaseEvent(QKeyEvent* event) override; 27 | void wheelEvent(QWheelEvent* event) override; 28 | void initMatrix(); 29 | void checkKey(); 30 | 31 | private: 32 | std::shared_ptr m_cube = nullptr; 33 | std::shared_ptr m_skyBox = nullptr; 34 | QOpenGLShaderProgram m_program; 35 | QMatrix4x4 m_model, m_view, m_project; 36 | #ifdef _DEBUG 37 | QOpenGLDebugLogger m_logger; 38 | #endif 39 | 40 | QVector2D m_mousePressPosition; 41 | QVector3D m_rotationAxis; 42 | float m_angularSpeed = 0; 43 | 44 | QQuaternion m_rotation; 45 | 46 | const float c_near = 0.1f; 47 | const float c_far = 100.0f; 48 | qreal m_elapsed = 100; 49 | qreal m_yaw = -90; 50 | qreal m_pitch = 0; 51 | qreal m_aspect = 45; 52 | 53 | QVector3D m_cameraPos = { 0.0f, 0.0f, 3.0f }; 54 | QVector3D m_cameraFront = { 0.0f, 0.0f, -1.0f }; 55 | QVector3D m_cameraUp = { 0.0f, 1.0f, 0.0f }; 56 | QPoint m_last; 57 | bool m_keys[1024] = { false }; 58 | }; 59 | -------------------------------------------------------------------------------- /SkyBox/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "TWindow.h" 2 | 3 | #include 4 | #include 5 | int main(int argc, char* argv[]) 6 | { 7 | QApplication app(argc, argv); 8 | 9 | QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); 10 | fmt.setVersion(3, 3); 11 | fmt.setDepthBufferSize(24); 12 | fmt.setProfile(QSurfaceFormat::CoreProfile); 13 | #ifdef _DEBUG 14 | fmt.setOption(QSurfaceFormat::DebugContext); 15 | #endif 16 | QSurfaceFormat::setDefaultFormat(fmt); 17 | TWindow w; 18 | w.show(); 19 | return app.exec(); 20 | } 21 | -------------------------------------------------------------------------------- /clang-foramt-All.ps1: -------------------------------------------------------------------------------- 1 | $scriptDir=$PSScriptRoot 2 | $currentDir=Get-Location 3 | Write-Host "currentDir" $currentDir 4 | Write-Host "scriptDir" $scriptDir 5 | $names="*.h","*.cpp","*.c","*.hpp" 6 | Get-ChildItem -Include $names -Recurse $currentDir | ForEach-Object { 7 | clang-format -i $_.FullName 8 | } -------------------------------------------------------------------------------- /img/CubeMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/CubeMap.png -------------------------------------------------------------------------------- /img/DepthTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/DepthTest.png -------------------------------------------------------------------------------- /img/FrameBufferObject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/FrameBufferObject.png -------------------------------------------------------------------------------- /img/HelloCube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/HelloCube.png -------------------------------------------------------------------------------- /img/HelloFBO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/HelloFBO.png -------------------------------------------------------------------------------- /img/HelloMix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/HelloMix.png -------------------------------------------------------------------------------- /img/HelloTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/HelloTexture.png -------------------------------------------------------------------------------- /img/QuickOpenGL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/QuickOpenGL.png -------------------------------------------------------------------------------- /img/Renderer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/Renderer.png -------------------------------------------------------------------------------- /img/SkyBox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/SkyBox.png -------------------------------------------------------------------------------- /img/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/light.png -------------------------------------------------------------------------------- /img/lightCasters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/lightCasters.png -------------------------------------------------------------------------------- /img/material.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/material.png -------------------------------------------------------------------------------- /img/mulitLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/img/mulitLight.png -------------------------------------------------------------------------------- /light/light.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-09-22T10:04:40 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | CONFIG += c++11 utf8_source 9 | 10 | TEMPLATE = app 11 | DEFINES += GL_DEBUG 12 | 13 | HEADERS += \ 14 | src/cube.h \ 15 | src/window.h 16 | 17 | SOURCES += \ 18 | src/cube.cpp \ 19 | src/main.cpp \ 20 | src/window.cpp 21 | 22 | RESOURCES += \ 23 | res/shader.qrc \ 24 | res/texture.qrc 25 | 26 | 27 | include($$PWD/../Common/Common.pri) 28 | -------------------------------------------------------------------------------- /light/res/image/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/light/res/image/cube.png -------------------------------------------------------------------------------- /light/res/image/cube1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/light/res/image/cube1.png -------------------------------------------------------------------------------- /light/res/image/pu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/light/res/image/pu.png -------------------------------------------------------------------------------- /light/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fshader.glsl 4 | shader/vshader.glsl 5 | shader/light.fsh 6 | shader/light.vsh 7 | 8 | 9 | -------------------------------------------------------------------------------- /light/res/shader/fshader.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | #ifdef GL_ES 4 | // Set default precision to medium 5 | precision mediump int; 6 | precision mediump float; 7 | #endif 8 | 9 | uniform vec3 lightPos; 10 | uniform vec3 lightColor; 11 | uniform sampler2D texture; 12 | uniform vec3 viewPos; 13 | 14 | in vec2 v_texcoord; 15 | in vec3 v_normal; 16 | in vec3 v_fragPos; 17 | 18 | out vec4 fragColor; 19 | 20 | //! [0] 21 | void main() 22 | { 23 | 24 | 25 | //ambient 环境光 26 | float ambientStrength = 0.1f; 27 | vec3 ambient = ambientStrength * lightColor; 28 | 29 | //diffuse 漫反射光 30 | vec3 norm = normalize(v_normal); 31 | vec3 lightDir = normalize(lightPos - v_fragPos); 32 | float diff = max(dot(norm, lightDir), 0.0); 33 | vec3 diffuse = diff * lightColor; 34 | 35 | //纹理颜色 36 | vec4 rgb = texture(texture, v_texcoord); 37 | 38 | //镜面高光 39 | float specularStrength = 0.9f; 40 | vec3 viewDir = normalize(viewPos - v_fragPos); 41 | vec3 reflectDir = reflect(-lightDir, norm); 42 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 43 | vec3 specular = specularStrength * spec * lightColor; 44 | 45 | fragColor = vec4(ambient + diffuse + specular, 1.0) * rgb; 46 | } 47 | //! [0] 48 | 49 | -------------------------------------------------------------------------------- /light/res/shader/light.fsh: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | #ifdef GL_ES 4 | // Set default precision to medium 5 | precision mediump int; 6 | precision mediump float; 7 | #endif 8 | uniform vec3 lightColor; 9 | 10 | in vec2 v_texcoord; 11 | 12 | out vec4 fragColor; 13 | 14 | void main(void) 15 | { 16 | fragColor = vec4(lightColor, 1.0); 17 | } 18 | -------------------------------------------------------------------------------- /light/res/shader/light.vsh: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | #ifdef GL_ES 4 | // Set default precision to medium 5 | precision mediump int; 6 | precision mediump float; 7 | #endif 8 | 9 | uniform mat4 modelMat; 10 | uniform mat4 viewMat; 11 | uniform mat4 projectMat; 12 | 13 | layout (location = 0) in vec4 a_position; 14 | layout (location = 1) in vec2 a_texcoord; 15 | layout (location = 2) in vec2 a_normal; 16 | 17 | out vec2 v_texcoord; 18 | 19 | void main(void) 20 | { 21 | v_texcoord = a_texcoord; 22 | gl_Position = projectMat * viewMat * modelMat * a_position; 23 | } 24 | -------------------------------------------------------------------------------- /light/res/shader/vshader.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | #ifdef GL_ES 4 | // Set default precision to medium 5 | precision mediump int; 6 | precision mediump float; 7 | #endif 8 | uniform mat4 modelMat; 9 | uniform mat4 viewMat; 10 | uniform mat4 projectMat; 11 | 12 | layout (location = 0) in vec3 a_position; 13 | layout (location = 1) in vec2 a_texcoord; 14 | layout (location = 2) in vec3 a_normal; 15 | 16 | out vec2 v_texcoord; 17 | out vec3 v_normal; 18 | out vec3 v_fragPos; 19 | 20 | void main() 21 | { 22 | // Calculate vertex position in screen space 23 | v_texcoord = a_texcoord; 24 | // v_normal = mat3(transpose(inverse(modelMat))) *a_normal; 25 | v_normal = a_normal; 26 | gl_Position = projectMat * viewMat * modelMat * vec4(a_position, 1.0f); 27 | v_fragPos = vec3(modelMat * vec4(a_position, 1.0f)); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /light/res/texture.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/cube.png 4 | image/cube1.png 5 | image/pu.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /light/src/cube.cpp: -------------------------------------------------------------------------------- 1 | #include "cube.h" 2 | #include 3 | #include 4 | 5 | #define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0])) 6 | struct VertexData 7 | { 8 | QVector3D position; 9 | QVector2D texCoord; 10 | }; 11 | 12 | const QVector3D Coords[] = { 13 | // v1 front top left 14 | QVector3D(-1.0f, 1.0f, 1.0f), 15 | // v2 front top right 16 | QVector3D(1.0f, 1.0f, 1.0f), 17 | // v3 front bottom left 18 | QVector3D(-1.0f, -1.0f, 1.0f), 19 | // v4 front bottom right 20 | QVector3D(1.0f, -1.0f, 1.0f), 21 | 22 | // v5 back top left 23 | QVector3D(-1.0f, 1.0f, -1.0f), 24 | // v6 back top right 25 | QVector3D(1.0f, 1.0f, -1.0f), 26 | // v7 back bottom left 27 | QVector3D(-1.0f, -1.0f, -1.0f), 28 | // v8 back bottom right 29 | QVector3D(1.0f, -1.0f, -1.0f), 30 | }; 31 | enum 32 | { 33 | COORD_F_T_L = 0, 34 | COORD_F_T_R, 35 | COORD_F_B_L, 36 | COORD_F_B_R, 37 | 38 | COORD_B_T_L, 39 | COORD_B_T_R, 40 | COORD_B_B_L, 41 | COORD_B_B_R, 42 | }; 43 | enum 44 | { 45 | v1 = COORD_F_T_L, 46 | v2, 47 | v3, 48 | v4, 49 | v5, 50 | v6, 51 | v7, 52 | v8 53 | }; 54 | Cube::Cube(QOpenGLShaderProgram* program) 55 | { 56 | initializeOpenGLFunctions(); 57 | // Initializes cube geometry and transfers it to VBOs 58 | initCube(); 59 | bindCube(program); 60 | } 61 | Cube::~Cube() { } 62 | 63 | void Cube::initCube() 64 | { 65 | // back 66 | vertices << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) 67 | << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f); 68 | 69 | normals << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) 70 | << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f); 71 | 72 | coords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0); 73 | 74 | // front 75 | vertices << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) 76 | << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, -0.5, 0.5f); 77 | 78 | normals << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) 79 | << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f); 80 | 81 | coords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0); 82 | 83 | // left 84 | vertices << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f) 85 | << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(-0.5, 0.5, 0.5f); 86 | 87 | normals << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) 88 | << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f); 89 | 90 | coords << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 1) << QVector2D(0, 0) << QVector2D(1, 0); 91 | 92 | // right 93 | vertices << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) 94 | << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f); 95 | 96 | normals << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) 97 | << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f); 98 | 99 | coords << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 1) << QVector2D(0, 0) << QVector2D(1, 0); 100 | // down 101 | vertices << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, -0.5, 0.5f) 102 | << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(-0.5, -0.5, -0.5f); 103 | 104 | normals << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) 105 | << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f); 106 | 107 | coords << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0) << QVector2D(1, 0) << QVector2D(0, 0) << QVector2D(0, 1); 108 | 109 | // up 110 | vertices << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) 111 | << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, 0.5, -0.5f); 112 | 113 | normals << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) 114 | << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f); 115 | 116 | coords << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0) << QVector2D(1, 0) << QVector2D(0, 0) << QVector2D(0, 1); 117 | } 118 | void Cube::bindCube(QOpenGLShaderProgram* program) 119 | { 120 | bool ok1 = program->link(); 121 | bool ok2 = program->bind(); 122 | qWarning() << "program bind " << ok1 << ok2; 123 | program->bindAttributeLocation("a_position", 0); 124 | program->bindAttributeLocation("a_texcoord", 1); 125 | program->bindAttributeLocation("a_normal", 2); 126 | 127 | glGenVertexArrays(1, &vao); 128 | glBindVertexArray(vao); 129 | { 130 | 131 | int verticesLoc = 0; 132 | int coordLoc = 1; 133 | int normalLoc = 2; 134 | program->enableAttributeArray(verticesLoc); 135 | program->setAttributeArray(verticesLoc, vertices.constData()); 136 | 137 | program->enableAttributeArray(coordLoc); 138 | program->setAttributeArray(coordLoc, coords.constData()); 139 | 140 | program->enableAttributeArray(normalLoc); 141 | 142 | program->setAttributeArray(normalLoc, normals.constData()); 143 | } 144 | glBindVertexArray(0); 145 | } 146 | void Cube::drawCube(QOpenGLShaderProgram* program) 147 | { 148 | glBindVertexArray(vao); 149 | glDrawArrays(GL_TRIANGLES, 0, vertices.size()); 150 | glBindVertexArray(0); 151 | } 152 | -------------------------------------------------------------------------------- /light/src/cube.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_H 2 | #define CUBE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Cube : protected QOpenGLExtraFunctions 9 | { 10 | public: 11 | Cube(QOpenGLShaderProgram* program); 12 | virtual ~Cube(); 13 | void drawCube(QOpenGLShaderProgram* program); 14 | 15 | private: 16 | void initCube(); 17 | void bindCube(QOpenGLShaderProgram* program); 18 | GLuint vao; 19 | QVector vertices; 20 | QVector normals; 21 | QVector cubePositions; 22 | QVector coords; 23 | }; 24 | 25 | #endif // CUBE_H 26 | -------------------------------------------------------------------------------- /light/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "GLCommon.h" 2 | #include "window.h" 3 | #include 4 | int main(int argc, char* argv[]) 5 | { 6 | GLCommon::prepareApp(); 7 | QGuiApplication a(argc, argv); 8 | GLCommon::prepareGL(); 9 | Window win; 10 | win.show(); 11 | return a.exec(); 12 | } 13 | -------------------------------------------------------------------------------- /light/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include "cube.h" 5 | 6 | #include "GLWindow.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | class Cube; 18 | 19 | class Window : public GLWindow 20 | { 21 | Q_OBJECT 22 | public: 23 | explicit Window(QWindow* parent = 0); 24 | ~Window(); 25 | 26 | protected: 27 | void mousePressEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 28 | void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 29 | 30 | void initializeGL() Q_DECL_OVERRIDE; 31 | void paintGL() Q_DECL_OVERRIDE; 32 | void resizeGL(int w, int h) Q_DECL_OVERRIDE; 33 | 34 | void initShaders(); 35 | void initTextures(); 36 | void initMatrixs(); 37 | void useLightShader(); 38 | void useMaterialShader(); 39 | 40 | private: 41 | void paintFPS(); 42 | void timerEvent(QTimerEvent* event) override; 43 | private slots: 44 | void processTimeout(); 45 | 46 | private: 47 | QOpenGLShaderProgram program; 48 | QOpenGLShader * materialV, *materialF; 49 | QOpenGLShader * lightF, *lightV; 50 | Cube* cube; 51 | 52 | QOpenGLTexture* texture; 53 | 54 | QMatrix4x4 projection; 55 | QMatrix4x4 model; 56 | QMatrix4x4 view; 57 | 58 | QVector3D lightPos; 59 | QVector2D mousePressPosition; 60 | QVector3D rotationAxis; 61 | 62 | QVector3D lightColor; 63 | qreal angularSpeed; 64 | QQuaternion rotation; 65 | }; 66 | 67 | #endif // WINDOW_H 68 | -------------------------------------------------------------------------------- /lightCasters/lightCasters.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-09-22T10:04:40 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui widgets 8 | 9 | CONFIG += c+=11 10 | 11 | TEMPLATE = app 12 | 13 | HEADERS += \ 14 | src/cube.h \ 15 | src/window.h 16 | 17 | SOURCES += \ 18 | src/cube.cpp \ 19 | src/main.cpp \ 20 | src/window.cpp 21 | 22 | RESOURCES += \ 23 | res/shader.qrc \ 24 | res/texture.qrc 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /lightCasters/res/image/container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/lightCasters/res/image/container.png -------------------------------------------------------------------------------- /lightCasters/res/image/container2_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/lightCasters/res/image/container2_specular.png -------------------------------------------------------------------------------- /lightCasters/res/image/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/lightCasters/res/image/cube.png -------------------------------------------------------------------------------- /lightCasters/res/image/cube1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/lightCasters/res/image/cube1.png -------------------------------------------------------------------------------- /lightCasters/res/image/pu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/lightCasters/res/image/pu.png -------------------------------------------------------------------------------- /lightCasters/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fshader.glsl 4 | shader/vshader.glsl 5 | shader/light.fsh 6 | shader/light.vsh 7 | 8 | 9 | -------------------------------------------------------------------------------- /lightCasters/res/shader/fshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | struct Material { 7 | sampler2D diffuse; 8 | sampler2D specular; 9 | float shininess; 10 | }; 11 | 12 | struct Light { 13 | vec3 direction; 14 | vec3 ambient; 15 | vec3 diffuse; 16 | vec3 specular; 17 | vec3 position; 18 | float constant; 19 | float linear; 20 | float quadratic; 21 | 22 | float cutoff; 23 | float outerCutOff; 24 | }; 25 | uniform Light light; 26 | uniform Material material; 27 | 28 | uniform vec3 viewPos; 29 | 30 | varying vec2 v_texcoord; 31 | varying vec3 v_normal; 32 | varying vec3 v_fragPos; 33 | //! [0] 34 | void main() 35 | { 36 | vec3 texDiffuse = vec3(texture2D(material.diffuse, v_texcoord)); 37 | 38 | 39 | //ambient 环境光 40 | vec3 ambient = light.ambient * texDiffuse; 41 | 42 | //diffuse 漫反射光 43 | vec3 norm = normalize(v_normal); 44 | //平行光,直接用方向向量 45 | // vec3 lightDir = normalize(-light.direction); 46 | //点光, 可以增加衰减 47 | vec3 lightDir = normalize(light.position - v_fragPos); 48 | 49 | //手电筒区域计算 50 | float theta = dot(lightDir, normalize(-light.direction)); 51 | float epsilon = light.cutoff - light.outerCutOff; 52 | float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); 53 | 54 | //计算距离和衰减系数 55 | float distance = length(light.position - v_fragPos); 56 | float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 57 | 58 | 59 | float diff = max(dot(norm, lightDir), 0.0); 60 | vec3 diffuse = light.diffuse * diff * texDiffuse; 61 | 62 | //镜面高光 63 | float specularStrength = 0.9f; 64 | vec3 viewDir = normalize(viewPos - v_fragPos); 65 | vec3 reflectDir = reflect(-lightDir, norm); 66 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 67 | vec3 specular = light.specular * spec * vec3(texture2D(material.specular, v_texcoord)); 68 | 69 | gl_FragColor = vec4(attenuation * (ambient + (intensity * diffuse) + (intensity * specular)), 1.0) ; 70 | 71 | } 72 | //! [0] 73 | 74 | -------------------------------------------------------------------------------- /lightCasters/res/shader/light.fsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | uniform vec3 lightColor; 7 | 8 | varying vec2 v_texcoord; 9 | 10 | void main(void) 11 | { 12 | gl_FragColor = vec4(lightColor, 1.0); 13 | } 14 | -------------------------------------------------------------------------------- /lightCasters/res/shader/light.vsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | uniform mat4 modelMat; 8 | uniform mat4 viewMat; 9 | uniform mat4 projectMat; 10 | 11 | attribute vec4 a_position; 12 | attribute vec2 a_texcoord; 13 | 14 | varying vec2 v_texcoord; 15 | void main(void) 16 | { 17 | v_texcoord = a_texcoord; 18 | gl_Position = projectMat * viewMat * modelMat * a_position; 19 | } 20 | -------------------------------------------------------------------------------- /lightCasters/res/shader/vshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | uniform mat4 modelMat; 7 | uniform mat4 viewMat; 8 | uniform mat4 projectMat; 9 | 10 | attribute vec3 a_position; 11 | attribute vec2 a_texcoord; 12 | attribute vec3 a_normal; 13 | 14 | varying vec2 v_texcoord; 15 | varying vec3 v_normal; 16 | varying vec3 v_fragPos; 17 | void main() 18 | { 19 | // Calculate vertex position in screen space 20 | v_texcoord = a_texcoord; 21 | v_normal = mat3(transpose(inverse(modelMat))) *a_normal; 22 | // v_normal = a_normal; 23 | gl_Position = projectMat * viewMat * modelMat * vec4(a_position, 1.0f); 24 | v_fragPos = vec3(modelMat * vec4(a_position, 1.0f)); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /lightCasters/res/texture.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/cube.png 4 | image/cube1.png 5 | image/pu.png 6 | image/container.png 7 | image/container2_specular.png 8 | 9 | 10 | -------------------------------------------------------------------------------- /lightCasters/src/cube.cpp: -------------------------------------------------------------------------------- 1 | #include "cube.h" 2 | #include 3 | #include 4 | 5 | #define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0])) 6 | struct VertexData 7 | { 8 | QVector3D position; 9 | QVector2D texCoord; 10 | }; 11 | 12 | const QVector3D Coords[] = { 13 | // v1 front top left 14 | QVector3D(-1.0f, 1.0f, 1.0f), 15 | // v2 front top right 16 | QVector3D(1.0f, 1.0f, 1.0f), 17 | // v3 front bottom left 18 | QVector3D(-1.0f, -1.0f, 1.0f), 19 | // v4 front bottom right 20 | QVector3D(1.0f, -1.0f, 1.0f), 21 | 22 | // v5 back top left 23 | QVector3D(-1.0f, 1.0f, -1.0f), 24 | // v6 back top right 25 | QVector3D(1.0f, 1.0f, -1.0f), 26 | // v7 back bottom left 27 | QVector3D(-1.0f, -1.0f, -1.0f), 28 | // v8 back bottom right 29 | QVector3D(1.0f, -1.0f, -1.0f), 30 | }; 31 | enum 32 | { 33 | COORD_F_T_L = 0, 34 | COORD_F_T_R, 35 | COORD_F_B_L, 36 | COORD_F_B_R, 37 | 38 | COORD_B_T_L, 39 | COORD_B_T_R, 40 | COORD_B_B_L, 41 | COORD_B_B_R, 42 | }; 43 | enum 44 | { 45 | v1 = COORD_F_T_L, 46 | v2, 47 | v3, 48 | v4, 49 | v5, 50 | v6, 51 | v7, 52 | v8 53 | }; 54 | Cube::Cube() 55 | { 56 | initializeOpenGLFunctions(); 57 | 58 | // Initializes cube geometry and transfers it to VBOs 59 | initCube(); 60 | } 61 | Cube::~Cube() { } 62 | 63 | void Cube::initCube() 64 | { 65 | // back 66 | vertices << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) 67 | << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f); 68 | 69 | normals << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) 70 | << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f); 71 | 72 | coords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0); 73 | 74 | // front 75 | vertices << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) 76 | << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, -0.5, 0.5f); 77 | 78 | normals << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) 79 | << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f); 80 | 81 | coords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0); 82 | 83 | // left 84 | vertices << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f) 85 | << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(-0.5, 0.5, 0.5f); 86 | 87 | normals << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) 88 | << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f); 89 | 90 | coords << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 1) << QVector2D(0, 0) << QVector2D(1, 0); 91 | 92 | // right 93 | vertices << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) 94 | << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f); 95 | 96 | normals << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) 97 | << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f); 98 | 99 | coords << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 1) << QVector2D(0, 0) << QVector2D(1, 0); 100 | // down 101 | vertices << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, -0.5, 0.5f) 102 | << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(-0.5, -0.5, -0.5f); 103 | 104 | normals << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) 105 | << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f); 106 | 107 | coords << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0) << QVector2D(1, 0) << QVector2D(0, 0) << QVector2D(0, 1); 108 | 109 | // up 110 | vertices << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) 111 | << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, 0.5, -0.5f); 112 | 113 | normals << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) 114 | << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f); 115 | 116 | coords << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0) << QVector2D(1, 0) << QVector2D(0, 0) << QVector2D(0, 1); 117 | } 118 | void Cube::drawCube(QOpenGLShaderProgram* program) 119 | { 120 | int verticesLoc = program->attributeLocation("a_position"); 121 | int coordLoc = program->attributeLocation("a_texcoord"); 122 | int normalLoc = program->attributeLocation("a_normal"); 123 | program->enableAttributeArray(verticesLoc); 124 | program->setAttributeArray(verticesLoc, vertices.constData()); 125 | 126 | program->enableAttributeArray(coordLoc); 127 | program->setAttributeArray(coordLoc, coords.constData()); 128 | 129 | program->enableAttributeArray(normalLoc); 130 | 131 | program->setAttributeArray(normalLoc, normals.constData()); 132 | 133 | glDrawArrays(GL_TRIANGLES, 0, vertices.size()); 134 | program->disableAttributeArray(verticesLoc); 135 | program->disableAttributeArray(coordLoc); 136 | program->disableAttributeArray(normalLoc); 137 | } 138 | -------------------------------------------------------------------------------- /lightCasters/src/cube.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_H 2 | #define CUBE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Cube : protected QOpenGLFunctions 9 | { 10 | public: 11 | Cube(); 12 | virtual ~Cube(); 13 | void drawCube(QOpenGLShaderProgram* program); 14 | 15 | private: 16 | void initCube(); 17 | 18 | QVector vertices; 19 | QVector normals; 20 | QVector cubePositions; 21 | QVector coords; 22 | }; 23 | 24 | #endif // CUBE_H 25 | -------------------------------------------------------------------------------- /lightCasters/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef QT_NO_OPENGL 6 | #include "window.h" 7 | #endif 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | QApplication app(argc, argv); 12 | 13 | QSurfaceFormat format; 14 | // format.setVersion(3,3); 15 | // format.setProfile(QSurfaceFormat::CoreProfile); 16 | format.setDepthBufferSize(24); 17 | QSurfaceFormat::setDefaultFormat(format); 18 | 19 | app.setApplicationName("cube"); 20 | app.setApplicationVersion("0.1"); 21 | #ifndef QT_NO_OPENGL 22 | Window win; 23 | win.show(); 24 | #else 25 | QLabel note("OpenGL Support required"); 26 | note.show(); 27 | #endif 28 | return app.exec(); 29 | } 30 | -------------------------------------------------------------------------------- /lightCasters/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include "cube.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | class Cube; 18 | 19 | class Window 20 | : public QOpenGLWidget 21 | , protected QOpenGLFunctions 22 | { 23 | Q_OBJECT 24 | public: 25 | explicit Window(QWidget* parent = 0); 26 | ~Window(); 27 | 28 | protected: 29 | void keyPressEvent(QKeyEvent* event) override; 30 | void mousePressEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 31 | void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 32 | 33 | void initializeGL() Q_DECL_OVERRIDE; 34 | void paintGL() Q_DECL_OVERRIDE; 35 | void resizeGL(int w, int h) Q_DECL_OVERRIDE; 36 | 37 | void initShaders(); 38 | void initTextures(); 39 | void initDatas(); 40 | void useLightShader(); 41 | void useMaterialShader(); 42 | private slots: 43 | void processTimeout(); 44 | 45 | private: 46 | void calcFPS(); 47 | void updateFPS(qreal); 48 | void paintFPS(); 49 | 50 | private: 51 | QTimer timer; 52 | QOpenGLShaderProgram program; 53 | QOpenGLShader * materialV, *materialF; 54 | QOpenGLShader * lightF, *lightV; 55 | Cube* cube; 56 | 57 | QOpenGLTexture *textureMaterial, *textureSpecular; 58 | 59 | QVector cubePositions; 60 | 61 | QMatrix4x4 projection; 62 | QMatrix4x4 model; 63 | QMatrix4x4 view; 64 | 65 | GLfloat shininess = 8.0; 66 | 67 | QVector3D lightAmibent; 68 | QVector3D lightDiffuse; 69 | QVector3D lightSpecular; 70 | 71 | QVector3D lightColor; 72 | QVector3D lightDir; 73 | QVector2D mousePressPosition; 74 | QVector3D rotationAxis; 75 | 76 | qreal angularSpeed; 77 | QQuaternion rotation; 78 | qreal fps; 79 | }; 80 | 81 | #endif // WINDOW_H 82 | -------------------------------------------------------------------------------- /material/material.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-09-22T10:04:40 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui widgets 8 | 9 | CONFIG += c+=11 10 | 11 | TEMPLATE = app 12 | 13 | HEADERS += \ 14 | src/cube.h \ 15 | src/window.h 16 | 17 | SOURCES += \ 18 | src/cube.cpp \ 19 | src/main.cpp \ 20 | src/window.cpp 21 | 22 | RESOURCES += \ 23 | res/shader.qrc \ 24 | res/texture.qrc 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /material/res/image/container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/material/res/image/container.png -------------------------------------------------------------------------------- /material/res/image/container2_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/material/res/image/container2_specular.png -------------------------------------------------------------------------------- /material/res/image/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/material/res/image/cube.png -------------------------------------------------------------------------------- /material/res/image/cube1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/material/res/image/cube1.png -------------------------------------------------------------------------------- /material/res/image/pu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/material/res/image/pu.png -------------------------------------------------------------------------------- /material/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/fshader.glsl 4 | shader/vshader.glsl 5 | shader/light.fsh 6 | shader/light.vsh 7 | 8 | 9 | -------------------------------------------------------------------------------- /material/res/shader/fshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | struct Material { 7 | sampler2D diffuse; 8 | sampler2D specular; 9 | float shininess; 10 | }; 11 | 12 | struct Light { 13 | vec3 position; 14 | vec3 ambient; 15 | vec3 diffuse; 16 | vec3 specular; 17 | }; 18 | uniform Light light; 19 | uniform Material material; 20 | 21 | uniform vec3 viewPos; 22 | 23 | varying vec2 v_texcoord; 24 | varying vec3 v_normal; 25 | varying vec3 v_fragPos; 26 | //! [0] 27 | void main() 28 | { 29 | vec3 texDiffuse = vec3(texture2D(material.diffuse, v_texcoord)); 30 | 31 | //ambient 环境光 32 | vec3 ambient = light.ambient * texDiffuse; 33 | 34 | //diffuse 漫反射光 35 | vec3 norm = normalize(v_normal); 36 | vec3 lightDir = normalize(light.position - v_fragPos); 37 | float diff = max(dot(norm, lightDir), 0.0); 38 | vec3 diffuse = light.diffuse * diff * texDiffuse; 39 | 40 | 41 | //镜面高光 42 | float specularStrength = 0.9f; 43 | vec3 viewDir = normalize(viewPos - v_fragPos); 44 | vec3 halfWayDir = normalize(lightDir + viewDir); 45 | float spec = pow(max(dot(norm, halfWayDir), 0.0), material.shininess); 46 | vec3 specular = light.specular * spec * vec3(texture2D(material.specular, v_texcoord)); 47 | // vec3 reflectDir = reflect(-lightDir, norm); 48 | // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 49 | // vec3 specular = light.specular * spec * vec3(texture2D(material.specular, v_texcoord)); 50 | 51 | gl_FragColor = vec4(ambient + diffuse + specular, 1.0) ; 52 | 53 | } 54 | //! [0] 55 | 56 | -------------------------------------------------------------------------------- /material/res/shader/light.fsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | uniform vec3 lightColor; 7 | 8 | varying vec2 v_texcoord; 9 | 10 | void main(void) 11 | { 12 | gl_FragColor = vec4(lightColor, 1.0); 13 | } 14 | -------------------------------------------------------------------------------- /material/res/shader/light.vsh: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | uniform mat4 modelMat; 8 | uniform mat4 viewMat; 9 | uniform mat4 projectMat; 10 | 11 | attribute vec4 a_position; 12 | attribute vec2 a_texcoord; 13 | 14 | varying vec2 v_texcoord; 15 | void main(void) 16 | { 17 | v_texcoord = a_texcoord; 18 | gl_Position = projectMat * viewMat * modelMat * a_position; 19 | } 20 | -------------------------------------------------------------------------------- /material/res/shader/vshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | uniform mat4 modelMat; 7 | uniform mat4 viewMat; 8 | uniform mat4 projectMat; 9 | 10 | attribute vec3 a_position; 11 | attribute vec2 a_texcoord; 12 | attribute vec3 a_normal; 13 | 14 | varying vec2 v_texcoord; 15 | varying vec3 v_normal; 16 | varying vec3 v_fragPos; 17 | void main() 18 | { 19 | // Calculate vertex position in screen space 20 | v_texcoord = a_texcoord; 21 | // v_normal = mat3(transpose(inverse(modelMat))) *a_normal; 22 | v_normal = a_normal; 23 | gl_Position = projectMat * viewMat * modelMat * vec4(a_position, 1.0f); 24 | v_fragPos = vec3(modelMat * vec4(a_position, 1.0f)); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /material/res/texture.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/cube.png 4 | image/cube1.png 5 | image/pu.png 6 | image/container.png 7 | image/container2_specular.png 8 | 9 | 10 | -------------------------------------------------------------------------------- /material/src/cube.cpp: -------------------------------------------------------------------------------- 1 | #include "cube.h" 2 | #include 3 | #include 4 | 5 | #define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0])) 6 | struct VertexData 7 | { 8 | QVector3D position; 9 | QVector2D texCoord; 10 | }; 11 | 12 | const QVector3D Coords[] = { 13 | // v1 front top left 14 | QVector3D(-1.0f, 1.0f, 1.0f), 15 | // v2 front top right 16 | QVector3D(1.0f, 1.0f, 1.0f), 17 | // v3 front bottom left 18 | QVector3D(-1.0f, -1.0f, 1.0f), 19 | // v4 front bottom right 20 | QVector3D(1.0f, -1.0f, 1.0f), 21 | 22 | // v5 back top left 23 | QVector3D(-1.0f, 1.0f, -1.0f), 24 | // v6 back top right 25 | QVector3D(1.0f, 1.0f, -1.0f), 26 | // v7 back bottom left 27 | QVector3D(-1.0f, -1.0f, -1.0f), 28 | // v8 back bottom right 29 | QVector3D(1.0f, -1.0f, -1.0f), 30 | }; 31 | enum 32 | { 33 | COORD_F_T_L = 0, 34 | COORD_F_T_R, 35 | COORD_F_B_L, 36 | COORD_F_B_R, 37 | 38 | COORD_B_T_L, 39 | COORD_B_T_R, 40 | COORD_B_B_L, 41 | COORD_B_B_R, 42 | }; 43 | enum 44 | { 45 | v1 = COORD_F_T_L, 46 | v2, 47 | v3, 48 | v4, 49 | v5, 50 | v6, 51 | v7, 52 | v8 53 | }; 54 | Cube::Cube() 55 | { 56 | initializeOpenGLFunctions(); 57 | 58 | // Initializes cube geometry and transfers it to VBOs 59 | initCube(); 60 | } 61 | Cube::~Cube() { } 62 | 63 | void Cube::initCube() 64 | { 65 | // back 66 | vertices << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) 67 | << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f); 68 | 69 | normals << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) 70 | << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f); 71 | 72 | coords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0); 73 | 74 | // front 75 | vertices << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) 76 | << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, -0.5, 0.5f); 77 | 78 | normals << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) 79 | << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f); 80 | 81 | coords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0); 82 | 83 | // left 84 | vertices << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f) 85 | << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(-0.5, 0.5, 0.5f); 86 | 87 | normals << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) 88 | << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f); 89 | 90 | coords << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 1) << QVector2D(0, 0) << QVector2D(1, 0); 91 | 92 | // right 93 | vertices << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) 94 | << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f); 95 | 96 | normals << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) 97 | << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f); 98 | 99 | coords << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 1) << QVector2D(0, 0) << QVector2D(1, 0); 100 | // down 101 | vertices << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, -0.5, 0.5f) 102 | << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(-0.5, -0.5, -0.5f); 103 | 104 | normals << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) 105 | << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f); 106 | 107 | coords << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0) << QVector2D(1, 0) << QVector2D(0, 0) << QVector2D(0, 1); 108 | 109 | // up 110 | vertices << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) 111 | << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, 0.5, -0.5f); 112 | 113 | normals << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) 114 | << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f); 115 | 116 | coords << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0) << QVector2D(1, 0) << QVector2D(0, 0) << QVector2D(0, 1); 117 | } 118 | void Cube::drawCube(QOpenGLShaderProgram* program) 119 | { 120 | int verticesLoc = program->attributeLocation("a_position"); 121 | int coordLoc = program->attributeLocation("a_texcoord"); 122 | int normalLoc = program->attributeLocation("a_normal"); 123 | program->enableAttributeArray(verticesLoc); 124 | program->setAttributeArray(verticesLoc, vertices.constData()); 125 | 126 | program->enableAttributeArray(coordLoc); 127 | program->setAttributeArray(coordLoc, coords.constData()); 128 | 129 | program->enableAttributeArray(normalLoc); 130 | 131 | program->setAttributeArray(normalLoc, normals.constData()); 132 | 133 | glDrawArrays(GL_TRIANGLES, 0, vertices.size()); 134 | program->disableAttributeArray(verticesLoc); 135 | program->disableAttributeArray(coordLoc); 136 | program->disableAttributeArray(normalLoc); 137 | } 138 | -------------------------------------------------------------------------------- /material/src/cube.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_H 2 | #define CUBE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Cube : protected QOpenGLFunctions 9 | { 10 | public: 11 | Cube(); 12 | virtual ~Cube(); 13 | void drawCube(QOpenGLShaderProgram* program); 14 | 15 | private: 16 | void initCube(); 17 | 18 | QVector vertices; 19 | QVector normals; 20 | QVector cubePositions; 21 | QVector coords; 22 | }; 23 | 24 | #endif // CUBE_H 25 | -------------------------------------------------------------------------------- /material/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef QT_NO_OPENGL 6 | #include "window.h" 7 | #endif 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | QApplication app(argc, argv); 12 | 13 | QSurfaceFormat format; 14 | 15 | format.setDepthBufferSize(24); 16 | QSurfaceFormat::setDefaultFormat(format); 17 | 18 | app.setApplicationName("cube"); 19 | app.setApplicationVersion("0.1"); 20 | #ifndef QT_NO_OPENGL 21 | Window win; 22 | win.show(); 23 | #else 24 | QLabel note("OpenGL Support required"); 25 | note.show(); 26 | #endif 27 | return app.exec(); 28 | } 29 | -------------------------------------------------------------------------------- /material/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include "cube.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | class Cube; 17 | 18 | class Window 19 | : public QOpenGLWidget 20 | , protected QOpenGLFunctions 21 | { 22 | Q_OBJECT 23 | public: 24 | explicit Window(QWidget* parent = 0); 25 | ~Window(); 26 | 27 | protected: 28 | void mousePressEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 29 | void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 30 | 31 | void initializeGL() Q_DECL_OVERRIDE; 32 | void paintGL() Q_DECL_OVERRIDE; 33 | void resizeGL(int w, int h) Q_DECL_OVERRIDE; 34 | 35 | void initShaders(); 36 | void initTextures(); 37 | void initDatas(); 38 | void useLightShader(); 39 | void useMaterialShader(); 40 | private slots: 41 | void processTimeout(); 42 | 43 | private: 44 | void calcFPS(); 45 | void updateFPS(qreal); 46 | void paintFPS(); 47 | 48 | private: 49 | QTimer timer; 50 | QOpenGLShaderProgram program; 51 | QOpenGLShader * materialV, *materialF; 52 | QOpenGLShader * lightF, *lightV; 53 | Cube* cube; 54 | 55 | QOpenGLTexture *textureMaterial, *textureSpecular; 56 | 57 | QMatrix4x4 projection; 58 | QMatrix4x4 model; 59 | QMatrix4x4 view; 60 | 61 | GLfloat shininess; 62 | 63 | QVector3D lightAmibent; 64 | QVector3D lightDiffuse; 65 | QVector3D lightSpecular; 66 | 67 | QVector3D lightColor; 68 | QVector3D lightPos; 69 | QVector2D mousePressPosition; 70 | QVector3D rotationAxis; 71 | 72 | qreal angularSpeed; 73 | QQuaternion rotation; 74 | qreal fps; 75 | }; 76 | 77 | #endif // WINDOW_H 78 | -------------------------------------------------------------------------------- /mulitLight/mulitLight.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-09-22T10:04:40 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui widgets 8 | 9 | CONFIG += c+=11 10 | 11 | TEMPLATE = app 12 | 13 | HEADERS += \ 14 | src/cube.h \ 15 | src/window.h 16 | 17 | SOURCES += \ 18 | src/cube.cpp \ 19 | src/main.cpp \ 20 | src/window.cpp 21 | 22 | RESOURCES += \ 23 | res/shader.qrc \ 24 | res/texture.qrc 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /mulitLight/res/image/container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/mulitLight/res/image/container.png -------------------------------------------------------------------------------- /mulitLight/res/image/container2_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/mulitLight/res/image/container2_specular.png -------------------------------------------------------------------------------- /mulitLight/res/image/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/mulitLight/res/image/cube.png -------------------------------------------------------------------------------- /mulitLight/res/image/cube1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/mulitLight/res/image/cube1.png -------------------------------------------------------------------------------- /mulitLight/res/image/pu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaredtao/QtOpenGL/18184b6163e7d6c496737de795fc63fe1879f010/mulitLight/res/image/pu.png -------------------------------------------------------------------------------- /mulitLight/res/shader.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shader/vshader.glsl 4 | shader/light.fsh 5 | shader/light.vsh 6 | shader/mulitlight.fsh 7 | 8 | 9 | -------------------------------------------------------------------------------- /mulitLight/res/shader/light.fsh: -------------------------------------------------------------------------------- 1 | //#version 430 core 2 | #ifdef GL_ES 3 | // Set default precision to medium 4 | precision mediump int; 5 | precision mediump float; 6 | #endif 7 | uniform vec3 lightColor; 8 | 9 | varying vec2 v_texcoord; 10 | 11 | void main(void) 12 | { 13 | gl_FragColor = vec4(lightColor, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /mulitLight/res/shader/light.vsh: -------------------------------------------------------------------------------- 1 | //#version 430 core 2 | #ifdef GL_ES 3 | // Set default precision to medium 4 | precision mediump int; 5 | precision mediump float; 6 | #endif 7 | 8 | uniform mat4 modelMat; 9 | uniform mat4 viewMat; 10 | uniform mat4 projectMat; 11 | 12 | attribute vec4 a_position; 13 | attribute vec2 a_texcoord; 14 | 15 | varying vec2 v_texcoord; 16 | void main(void) 17 | { 18 | v_texcoord = a_texcoord; 19 | gl_Position = projectMat * viewMat * modelMat * a_position; 20 | } 21 | -------------------------------------------------------------------------------- /mulitLight/res/shader/mulitlight.fsh: -------------------------------------------------------------------------------- 1 | //#version 430 core 2 | varying highp vec2 v_texcoord; 3 | varying vec3 v_normal; 4 | varying vec3 v_fragPos; 5 | 6 | uniform vec3 u_viewPos; 7 | 8 | struct Material { 9 | sampler2D diffuse; 10 | sampler2D specular; 11 | float shininess; 12 | }; 13 | 14 | struct DirLight{ 15 | vec3 direction; 16 | vec3 ambient; 17 | vec3 diffuse; 18 | vec3 specular; 19 | }; 20 | 21 | struct PointLight{ 22 | vec3 position; 23 | 24 | vec3 ambient; 25 | vec3 diffuse; 26 | vec3 specular; 27 | 28 | float constant; 29 | float linear; 30 | float quadratic; 31 | }; 32 | 33 | struct SpotLight{ 34 | vec3 position; 35 | vec3 direction; 36 | 37 | float cutoff; 38 | float outerCutOff; 39 | 40 | vec3 ambient; 41 | vec3 diffuse; 42 | vec3 specular; 43 | 44 | float constant; 45 | float linear; 46 | float quadratic; 47 | }; 48 | 49 | uniform Material material; 50 | uniform DirLight dirLight; 51 | uniform PointLight pointLights[4]; 52 | uniform SpotLight spotLight; 53 | 54 | vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); 55 | vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); 56 | vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); 57 | 58 | void main(void) 59 | { 60 | vec3 norm = normalize(v_normal); 61 | vec3 viewDir = normalize(u_viewPos - v_fragPos); 62 | 63 | vec3 result = CalcDirLight(dirLight, norm, viewDir); 64 | for (int i = 0; i < 4; i++) { 65 | result += CalcPointLight(pointLights[i], norm, v_fragPos, viewDir); 66 | 67 | } 68 | result += CalcSpotLight(spotLight, norm, v_fragPos, viewDir); 69 | gl_FragColor = vec4(result, 1.0); 70 | } 71 | 72 | 73 | vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir) 74 | { 75 | vec3 lightDir = normalize(-light.direction); 76 | vec3 texDiffuse = vec3(texture2D(material.diffuse, v_texcoord)); 77 | 78 | //ambient 环境光 79 | vec3 ambient = light.ambient * texDiffuse; 80 | 81 | //diffuse 漫反射光 82 | float diff = max(dot(normal, lightDir), 0.0); 83 | vec3 diffuse = light.diffuse * diff * texDiffuse; 84 | 85 | //specular 镜面光 86 | // vec3 reflectDir = reflect(-lightDir, normal); 87 | // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 88 | vec3 halfWayDir = normalize(lightDir + viewDir); 89 | float spec = pow(max(dot(normal, halfWayDir), 0.0), material.shininess); 90 | vec3 specular = light.specular * spec * vec3(texture2D(material.specular, v_texcoord)); 91 | 92 | return ambient + diffuse + specular; 93 | 94 | } 95 | 96 | vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) 97 | { 98 | vec3 texDiffuse = vec3 (texture2D(material.diffuse, v_texcoord)); 99 | vec3 lightDir = normalize(light.position - fragPos); 100 | 101 | //ambient 102 | vec3 ambient = light.ambient * texDiffuse; 103 | 104 | //diffuse 105 | float diff = max(dot(normal, lightDir), 0.0); 106 | vec3 diffuse = light.diffuse * diff * texDiffuse; 107 | 108 | //specular 109 | // vec3 reflectDir = reflect(-lightDir, normal); 110 | // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 111 | vec3 halfWayDir = normalize(lightDir + viewDir); 112 | float spec = pow(max(dot(normal, halfWayDir), 0.0), material.shininess); 113 | vec3 specular = light.specular * spec * vec3(texture2D(material.specular, v_texcoord)); 114 | 115 | //计算距离 和 衰减系数 116 | float distance = length(light.position - fragPos); 117 | float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 118 | 119 | return attenuation * (ambient + diffuse + specular); 120 | 121 | } 122 | vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) 123 | { 124 | vec3 texDiffuse = vec3 (texture2D(material.diffuse, v_texcoord)); 125 | vec3 lightDir = normalize(light.position - fragPos); 126 | 127 | //ambient 128 | vec3 ambient = light.ambient * texDiffuse; 129 | 130 | //diffuse 131 | float diff = max(dot(normal, lightDir), 0.0); 132 | vec3 diffuse = light.diffuse * diff * texDiffuse; 133 | 134 | //specular 135 | // vec3 reflectDir = reflect(-lightDir, normal); 136 | // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 137 | vec3 halfWayDir = normalize(lightDir + viewDir); 138 | float spec = pow(max(dot(normal, halfWayDir), 0.0), material.shininess); 139 | vec3 specular = light.specular * spec * vec3(texture2D(material.specular, v_texcoord)); 140 | 141 | //计算距离 和 衰减系数 142 | float distance = length(light.position - fragPos); 143 | float attenuation = 1.0f / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 144 | 145 | //手电筒区域计算 146 | float theta = dot(lightDir, normalize(-light.direction)); 147 | float epsilon = light.cutoff - light.outerCutOff; 148 | float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); 149 | 150 | return attenuation * intensity *(ambient + diffuse + specular); 151 | } 152 | -------------------------------------------------------------------------------- /mulitLight/res/shader/vshader.glsl: -------------------------------------------------------------------------------- 1 | //#version 430 core 2 | #ifdef GL_ES 3 | // Set default precision to medium 4 | precision mediump int; 5 | precision mediump float; 6 | #endif 7 | uniform mat4 modelMat; 8 | uniform mat4 viewMat; 9 | uniform mat4 projectMat; 10 | 11 | attribute vec3 a_position; 12 | attribute vec2 a_texcoord; 13 | attribute vec3 a_normal; 14 | 15 | varying vec2 v_texcoord; 16 | varying vec3 v_normal; 17 | varying vec3 v_fragPos; 18 | void main() 19 | { 20 | // Calculate vertex position in screen space 21 | v_texcoord = a_texcoord; 22 | v_normal = mat3(transpose(inverse(modelMat))) *a_normal; 23 | // v_normal = a_normal; 24 | v_fragPos = vec3(modelMat * vec4(a_position, 1.0f)); 25 | gl_Position = projectMat * viewMat * vec4(v_fragPos, 1.0f); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /mulitLight/res/texture.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | image/cube.png 4 | image/cube1.png 5 | image/pu.png 6 | image/container.png 7 | image/container2_specular.png 8 | 9 | 10 | -------------------------------------------------------------------------------- /mulitLight/src/cube.cpp: -------------------------------------------------------------------------------- 1 | #include "cube.h" 2 | #include 3 | #include 4 | 5 | #define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0])) 6 | struct VertexData 7 | { 8 | QVector3D position; 9 | QVector2D texCoord; 10 | }; 11 | 12 | const QVector3D Coords[] = { 13 | // v1 front top left 14 | QVector3D(-1.0f, 1.0f, 1.0f), 15 | // v2 front top right 16 | QVector3D(1.0f, 1.0f, 1.0f), 17 | // v3 front bottom left 18 | QVector3D(-1.0f, -1.0f, 1.0f), 19 | // v4 front bottom right 20 | QVector3D(1.0f, -1.0f, 1.0f), 21 | 22 | // v5 back top left 23 | QVector3D(-1.0f, 1.0f, -1.0f), 24 | // v6 back top right 25 | QVector3D(1.0f, 1.0f, -1.0f), 26 | // v7 back bottom left 27 | QVector3D(-1.0f, -1.0f, -1.0f), 28 | // v8 back bottom right 29 | QVector3D(1.0f, -1.0f, -1.0f), 30 | }; 31 | enum 32 | { 33 | COORD_F_T_L = 0, 34 | COORD_F_T_R, 35 | COORD_F_B_L, 36 | COORD_F_B_R, 37 | 38 | COORD_B_T_L, 39 | COORD_B_T_R, 40 | COORD_B_B_L, 41 | COORD_B_B_R, 42 | }; 43 | enum 44 | { 45 | v1 = COORD_F_T_L, 46 | v2, 47 | v3, 48 | v4, 49 | v5, 50 | v6, 51 | v7, 52 | v8 53 | }; 54 | Cube::Cube() 55 | { 56 | initializeOpenGLFunctions(); 57 | 58 | // Initializes cube geometry and transfers it to VBOs 59 | initCube(); 60 | } 61 | Cube::~Cube() { } 62 | 63 | void Cube::initCube() 64 | { 65 | // back 66 | vertices << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) 67 | << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f); 68 | 69 | normals << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f) 70 | << QVector3D(0.0f, 0.0f, -1.0f) << QVector3D(0.0f, 0.0f, -1.0f); 71 | 72 | coords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0); 73 | 74 | // front 75 | vertices << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) 76 | << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, -0.5, 0.5f); 77 | 78 | normals << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f) 79 | << QVector3D(0.0f, 0.0f, 1.0f) << QVector3D(0.0f, 0.0f, 1.0f); 80 | 81 | coords << QVector2D(0, 0) << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 0); 82 | 83 | // left 84 | vertices << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(-0.5, -0.5, -0.5f) 85 | << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(-0.5, 0.5, 0.5f); 86 | 87 | normals << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f) 88 | << QVector3D(-1.0f, 0.0f, 0.0f) << QVector3D(-1.0f, 0.0f, 0.0f); 89 | 90 | coords << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 1) << QVector2D(0, 0) << QVector2D(1, 0); 91 | 92 | // right 93 | vertices << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) 94 | << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f); 95 | 96 | normals << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f) 97 | << QVector3D(1.0f, 0.0f, 0.0f) << QVector3D(1.0f, 0.0f, 0.0f); 98 | 99 | coords << QVector2D(1, 0) << QVector2D(1, 1) << QVector2D(0, 1) << QVector2D(0, 1) << QVector2D(0, 0) << QVector2D(1, 0); 100 | // down 101 | vertices << QVector3D(-0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, -0.5f) << QVector3D(0.5, -0.5, 0.5f) << QVector3D(0.5, -0.5, 0.5f) 102 | << QVector3D(-0.5, -0.5, 0.5f) << QVector3D(-0.5, -0.5, -0.5f); 103 | 104 | normals << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f) 105 | << QVector3D(0.0f, -1.0f, 0.0f) << QVector3D(0.0f, -1.0f, 0.0f); 106 | 107 | coords << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0) << QVector2D(1, 0) << QVector2D(0, 0) << QVector2D(0, 1); 108 | 109 | // up 110 | vertices << QVector3D(-0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, -0.5f) << QVector3D(0.5, 0.5, 0.5f) << QVector3D(0.5, 0.5, 0.5f) 111 | << QVector3D(-0.5, 0.5, 0.5f) << QVector3D(-0.5, 0.5, -0.5f); 112 | 113 | normals << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f) 114 | << QVector3D(0.0f, 1.0f, 0.0f) << QVector3D(0.0f, 1.0f, 0.0f); 115 | 116 | coords << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0) << QVector2D(1, 0) << QVector2D(0, 0) << QVector2D(0, 1); 117 | } 118 | void Cube::drawCube(QOpenGLShaderProgram* program) 119 | { 120 | int verticesLoc = program->attributeLocation("a_position"); 121 | int coordLoc = program->attributeLocation("a_texcoord"); 122 | int normalLoc = program->attributeLocation("a_normal"); 123 | program->enableAttributeArray(verticesLoc); 124 | program->setAttributeArray(verticesLoc, vertices.constData()); 125 | 126 | program->enableAttributeArray(coordLoc); 127 | program->setAttributeArray(coordLoc, coords.constData()); 128 | 129 | program->enableAttributeArray(normalLoc); 130 | 131 | program->setAttributeArray(normalLoc, normals.constData()); 132 | 133 | glDrawArrays(GL_TRIANGLES, 0, vertices.size()); 134 | program->disableAttributeArray(verticesLoc); 135 | program->disableAttributeArray(coordLoc); 136 | program->disableAttributeArray(normalLoc); 137 | } 138 | -------------------------------------------------------------------------------- /mulitLight/src/cube.h: -------------------------------------------------------------------------------- 1 | #ifndef CUBE_H 2 | #define CUBE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Cube : protected QOpenGLFunctions 9 | { 10 | public: 11 | Cube(); 12 | virtual ~Cube(); 13 | void drawCube(QOpenGLShaderProgram* program); 14 | 15 | private: 16 | void initCube(); 17 | 18 | QVector vertices; 19 | QVector normals; 20 | QVector cubePositions; 21 | QVector coords; 22 | }; 23 | 24 | #endif // CUBE_H 25 | -------------------------------------------------------------------------------- /mulitLight/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef QT_NO_OPENGL 6 | #include "window.h" 7 | #endif 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | QApplication app(argc, argv); 12 | 13 | // QSurfaceFormat format; 14 | 15 | // format.setDepthBufferSize(24); 16 | // format.setVersion(4, 3); 17 | // QSurfaceFormat::setDefaultFormat(format); 18 | 19 | app.setApplicationName("cube"); 20 | app.setApplicationVersion("0.1"); 21 | #ifndef QT_NO_OPENGL 22 | Window win; 23 | win.show(); 24 | #else 25 | QLabel note("OpenGL Support required"); 26 | note.show(); 27 | #endif 28 | return app.exec(); 29 | } 30 | -------------------------------------------------------------------------------- /mulitLight/src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include "cube.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | class Cube; 17 | 18 | class Window 19 | : public QOpenGLWidget 20 | , protected QOpenGLFunctions 21 | { 22 | Q_OBJECT 23 | public: 24 | explicit Window(QWidget* parent = 0); 25 | ~Window(); 26 | 27 | protected: 28 | void mousePressEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 29 | void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE; 30 | 31 | void initializeGL() Q_DECL_OVERRIDE; 32 | void paintGL() Q_DECL_OVERRIDE; 33 | void resizeGL(int w, int h) Q_DECL_OVERRIDE; 34 | 35 | void initShaders(); 36 | void initTextures(); 37 | void initDatas(); 38 | void useLightShader(); 39 | void useMaterialShader(); 40 | private slots: 41 | void processTimeout(); 42 | 43 | private: 44 | void calcFPS(); 45 | void updateFPS(qreal); 46 | void paintFPS(); 47 | 48 | private: 49 | QTimer timer; 50 | QOpenGLShaderProgram program; 51 | QOpenGLShader * materialV, *materialF; 52 | QOpenGLShader * lightF, *lightV; 53 | Cube* cube; 54 | 55 | QOpenGLTexture *textureMaterial, *textureSpecular; 56 | 57 | QVector cubePositions; 58 | QVector poitLightPositions; 59 | 60 | QMatrix4x4 projection; 61 | QMatrix4x4 model; 62 | QMatrix4x4 view; 63 | 64 | GLfloat shininess; 65 | 66 | QVector3D lightAmibent; 67 | QVector3D lightDiffuse; 68 | QVector3D lightSpecular; 69 | 70 | QVector3D lightColor; 71 | QVector3D lightDir; 72 | QVector2D mousePressPosition; 73 | QVector3D rotationAxis; 74 | 75 | qreal angularSpeed; 76 | QQuaternion rotation; 77 | qreal fps; 78 | }; 79 | 80 | #endif // WINDOW_H 81 | --------------------------------------------------------------------------------