├── .clang-format ├── .github └── workflows │ └── ccpp.yml ├── .gitignore ├── CMakeLists.txt ├── License.txt ├── readme.md ├── screen-capture.jpg └── source ├── CMakeLists.txt ├── Info.plist ├── QCodeEditor.cpp ├── QCodeEditor.h ├── QColorButton.cpp ├── QColorButton.h ├── QVectorEdit.cpp ├── QVectorEdit.h ├── SGCanvas.cpp ├── SGCanvas.h ├── SGCanvasMouseHandler.cpp ├── SGCanvasMouseHandler.h ├── SGFixedGLState.cpp ├── SGFixedGLState.h ├── SGFrame.cpp ├── SGFrame.h ├── SGOglFogNBPage.cpp ├── SGOglFogNBPage.h ├── SGOglLightNBPage.cpp ├── SGOglLightNBPage.h ├── SGOglMaterialNBPage.cpp ├── SGOglMaterialNBPage.h ├── SGOglNotebook.cpp ├── SGOglNotebook.h ├── SGOglTextureCoordNBPage.cpp ├── SGOglTextureCoordNBPage.h ├── SGOglTextureEnvNBPage.cpp ├── SGOglTextureEnvNBPage.h ├── SGShaderGenerator.cpp ├── SGShaderGenerator.h ├── SGShaderTextWindow.cpp ├── SGShaderTextWindow.h ├── SGSurfaces.cpp ├── SGSurfaces.h ├── SGTextures.cpp ├── SGTextures.h ├── SgFrame.ui ├── ShaderGen.desktop ├── ShaderGen.icns ├── ShaderGen.ico ├── ShaderGen.png ├── globals.h ├── info.rc ├── main.cpp ├── textures ├── 3Dlabs.png ├── 3DlabsNormal.png ├── Leopard.png ├── bricksDiffuse.png ├── bricksNormal.png ├── cobblestonesDiffuse.png ├── cobblestonesNormal.png ├── eyeball.png ├── metalSheetDiffuse.png ├── metalSheetNormal.png ├── rust.png ├── stonewallDiffuse.png └── stonewallNormal.png ├── textures1.qrc └── textures2.qrc /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Mozilla 2 | IndentWidth: '4' 3 | ColumnLimit: 100 4 | -------------------------------------------------------------------------------- /.github/workflows/ccpp.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | env: 9 | BUILD_TYPE: Release 10 | 11 | jobs: 12 | build: 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | os: [macOS-latest, windows-latest, ubuntu-latest] 17 | runs-on: ${{ matrix.os }} 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Install Qt 22 | uses: jurplel/install-qt-action@v3 23 | with: 24 | version: 5.12.7 25 | - name: Configure 26 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 27 | - name: Build 28 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 29 | - name: Pack 30 | working-directory: ${{github.workspace}}/build 31 | shell: bash 32 | run: | 33 | if [ "${{ matrix.os }}" == "windows-latest" ]; then 34 | /c/Program\ Files/CMake/bin/cpack -G ZIP 35 | else 36 | cpack -G ZIP 37 | fi 38 | 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.user 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1.0) 2 | 3 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "Minimum OS X deployment version") 4 | 5 | project(ShaderGen) 6 | 7 | find_package(Git REQUIRED) 8 | 9 | execute_process( 10 | COMMAND ${GIT_EXECUTABLE} describe --always --tags 11 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 12 | OUTPUT_VARIABLE SHADERGEN_VERSION 13 | ERROR_QUIET 14 | OUTPUT_STRIP_TRAILING_WHITESPACE 15 | ) 16 | 17 | message( STATUS "VERSION: ${SHADERGEN_VERSION}") 18 | 19 | add_definitions(-DSHADERGEN_VERSION="${SHADERGEN_VERSION}") 20 | 21 | add_subdirectory(source) 22 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | 2 | Copyright (C) 2005 3Dlabs Inc. Ltd. 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 10 | Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following 15 | disclaimer in the documentation and/or other materials provided 16 | with the distribution. 17 | 18 | Neither the name of 3Dlabs Inc. Ltd. nor the names of its 19 | contributors may be used to endorse or promote products derived 20 | from this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 24 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 26 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 | COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 31 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 32 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 34 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 35 | OF SUCH DAMAGE. 36 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ShaderGen 2 | ========= 3 | 4 | ![C/C++ CI](https://github.com/mojocorp/ShaderGen/workflows/C/C++%20CI/badge.svg) 5 | [![GitHub Releases](https://img.shields.io/github/release/mojocorp/ShaderGen.svg)](https://github.com/mojocorp/ShaderGen/releases) 6 | [![License](https://img.shields.io/badge/License-BSD-blue.svg)](https://raw.githubusercontent.com/mojocorp/ShaderGen/master/License.txt) 7 | 8 | 9 | 10 | ### Description ### 11 | 12 | ShaderGen is a tool that automatically generates OpenGL Shading Language shaders that duplicate fixed function OpenGL behavior. 13 | 14 | ### Download ### 15 | 16 | [ShaderGen 3.5.0 Windows](https://github.com/mojocorp/ShaderGen/releases/download/3.5.0/ShaderGen-3.5.0.exe) 17 | [ShaderGen 3.5.0 Mac OS X Intel 64bit DMG](https://github.com/mojocorp/ShaderGen/releases/download/3.5.0/ShaderGen-3.5.0.dmg) 18 | [ShaderGen 3.5.0 Linux Ubuntu x64](https://github.com/mojocorp/ShaderGen/releases/download/3.5.0/ShaderGen-3.5.0-linux-x86_64.AppImage) 19 | 20 | ### Compiling ### 21 | 22 | * Download and install Qt 5.x 23 | * Download and install QtCreator 24 | * Load the CMakeLists.txt 25 | -------------------------------------------------------------------------------- /screen-capture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/screen-capture.jpg -------------------------------------------------------------------------------- /source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1.0) 2 | 3 | set(CMAKE_CXX_STANDARD 14) 4 | 5 | # Instruct CMake to run moc automatically when needed. 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | set(CMAKE_AUTORCC ON) 9 | 10 | find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED) 11 | find_package(OpenGL REQUIRED) 12 | 13 | set(HEADERS 14 | globals.h 15 | SGFrame.h 16 | SGFixedGLState.h 17 | SGOglNotebook.h 18 | SGSurfaces.h 19 | SGShaderGenerator.h 20 | SGShaderTextWindow.h 21 | SGCanvasMouseHandler.h 22 | SGCanvas.h 23 | SGTextures.h 24 | SGOglFogNBPage.h 25 | SGOglMaterialNBPage.h 26 | SGOglLightNBPage.h 27 | SGOglTextureCoordNBPage.h 28 | SGOglTextureEnvNBPage.h 29 | QColorButton.h 30 | QVectorEdit.h 31 | QCodeEditor.h 32 | ) 33 | 34 | set(SOURCES 35 | SGFrame.cpp 36 | SGFixedGLState.cpp 37 | SGOglNotebook.cpp 38 | SGSurfaces.cpp 39 | SGShaderGenerator.cpp 40 | SGCanvas.cpp 41 | SGCanvasMouseHandler.cpp 42 | SGShaderTextWindow.cpp 43 | SGOglFogNBPage.cpp 44 | SGOglMaterialNBPage.cpp 45 | SGTextures.cpp 46 | SGOglLightNBPage.cpp 47 | SGOglTextureCoordNBPage.cpp 48 | SGOglTextureEnvNBPage.cpp 49 | QColorButton.cpp 50 | QVectorEdit.cpp 51 | QCodeEditor.cpp 52 | main.cpp 53 | ) 54 | 55 | set(RESOURCES 56 | textures1.qrc 57 | textures2.qrc 58 | ) 59 | 60 | if (APPLE) 61 | set(RESOURCES ${RESOURCES} ShaderGen.icns) 62 | set_source_files_properties(ShaderGen.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) 63 | endif (APPLE) 64 | 65 | if (WIN32) 66 | set(RESOURCES ${RESOURCES} info.rc) 67 | 68 | # Remove weird Debug/Release subdirectories 69 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}) 70 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}) 71 | endif (WIN32) 72 | 73 | add_executable (ShaderGen WIN32 MACOSX_BUNDLE ${HEADERS} ${SOURCES} ${RESOURCES}) 74 | 75 | target_link_libraries(ShaderGen 76 | Qt5::Widgets 77 | Qt5::OpenGL 78 | ${OPENGL_LIBRARIES} 79 | ) 80 | 81 | # Install 82 | if (APPLE) 83 | set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${SHADERGEN_VERSION}) 84 | set(MACOSX_BUNDLE_BUNDLE_VERSION ${SHADERGEN_VERSION}) 85 | set_target_properties(ShaderGen PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) 86 | install(TARGETS ShaderGen BUNDLE DESTINATION ./) 87 | elseif (WIN32) 88 | set_target_properties(ShaderGen PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") 89 | install(TARGETS ShaderGen RUNTIME DESTINATION bin) 90 | else() 91 | # Assume linux 92 | install(TARGETS ShaderGen DESTINATION bin) 93 | endif () 94 | 95 | # Automatically deploy qt 96 | get_target_property(QT5_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) 97 | get_filename_component(QT5_BIN_DIR ${QT5_QMAKE_EXECUTABLE} PATH) 98 | if (APPLE) 99 | find_program(QT5_DEPLOYQT_EXECUTABLE macdeployqt HINTS "${QT5_BIN_DIR}") 100 | install(CODE "EXECUTE_PROCESS(COMMAND ${QT5_DEPLOYQT_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/ShaderGen.app)") 101 | 102 | install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ShaderGen.app/Contents/Frameworks DESTINATION ./ShaderGen.app/Contents) 103 | install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ShaderGen.app/Contents/PlugIns DESTINATION ./ShaderGen.app/Contents) 104 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ShaderGen.app/Contents/Resources/qt.conf DESTINATION ./ShaderGen.app/Contents/Resources) 105 | elseif (WIN32) 106 | find_program(QT5_DEPLOYQT_EXECUTABLE windeployqt HINTS "${QT5_BIN_DIR}") 107 | install(CODE "EXECUTE_PROCESS(COMMAND ${QT5_DEPLOYQT_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/ShaderGen.exe)") 108 | 109 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Qt5Core.dll DESTINATION bin) 110 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Qt5Gui.dll DESTINATION bin) 111 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Qt5Widgets.dll DESTINATION bin) 112 | install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/platforms DESTINATION bin) 113 | install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/styles DESTINATION bin) 114 | include(InstallRequiredSystemLibraries) 115 | else () 116 | # Assume linux 117 | install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ShaderGen.png DESTINATION bin) 118 | install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ShaderGen.desktop DESTINATION bin) 119 | endif () 120 | 121 | # Package builder 122 | set(CPACK_PACKAGE_NAME "ShaderGen") 123 | set(CPACK_PACKAGE_VENDOR "mojocorp") 124 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "GLSL ShaderGen") 125 | set(CPACK_PACKAGE_VERSION ${SHADERGEN_VERSION}) 126 | set(CPACK_PACKAGE_EXECUTABLES "ShaderGen" "ShaderGen") 127 | set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}") 128 | set(CPACK_NSIS_MODIFY_PATH OFF) 129 | set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) 130 | set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/License.txt") 131 | 132 | include(CPack) 133 | -------------------------------------------------------------------------------- /source/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ShaderGen 9 | CFBundleGetInfoString 10 | ShaderGen 11 | CFBundleIconFile 12 | ShaderGen.icns 13 | CFBundleIdentifier 14 | com.github.ShaderGen 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleLongVersionString 18 | 19 | CFBundleName 20 | ShaderGen 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | ${MACOSX_BUNDLE_SHORT_VERSION_STRING} 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | ${MACOSX_BUNDLE_BUNDLE_VERSION} 29 | CSResourcesFileMapped 30 | 31 | NSHumanReadableCopyright 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /source/QCodeEditor.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). 4 | ** Contact: http://www.qt-project.org/legal 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** You may use this file under the terms of the BSD license as follows: 10 | ** 11 | ** "Redistribution and use in source and binary forms, with or without 12 | ** modification, are permitted provided that the following conditions are 13 | ** met: 14 | ** * Redistributions of source code must retain the above copyright 15 | ** notice, this list of conditions and the following disclaimer. 16 | ** * Redistributions in binary form must reproduce the above copyright 17 | ** notice, this list of conditions and the following disclaimer in 18 | ** the documentation and/or other materials provided with the 19 | ** distribution. 20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names 21 | ** of its contributors may be used to endorse or promote products derived 22 | ** from this software without specific prior written permission. 23 | ** 24 | ** 25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 36 | ** 37 | ** $QT_END_LICENSE$ 38 | ** 39 | ****************************************************************************/ 40 | 41 | #include 42 | 43 | #include "QCodeEditor.h" 44 | 45 | class LineNumberArea : public QWidget 46 | { 47 | public: 48 | LineNumberArea(QCodeEditor* editor) 49 | : QWidget(editor) 50 | { 51 | codeEditor = editor; 52 | } 53 | 54 | QSize sizeHint() const override { return { codeEditor->lineNumberAreaWidth(), 0 }; } 55 | 56 | protected: 57 | void paintEvent(QPaintEvent* event) override { codeEditor->lineNumberAreaPaintEvent(event); } 58 | 59 | private: 60 | QCodeEditor* codeEditor; 61 | }; 62 | 63 | QCodeEditor::QCodeEditor(QWidget* parent) 64 | : QPlainTextEdit(parent) 65 | { 66 | m_lineNumberArea = new LineNumberArea(this); 67 | 68 | connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); 69 | connect(this, SIGNAL(updateRequest(QRect, int)), this, SLOT(updateLineNumberArea(QRect, int))); 70 | connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); 71 | 72 | updateLineNumberAreaWidth(0); 73 | highlightCurrentLine(); 74 | } 75 | 76 | int 77 | QCodeEditor::lineNumberAreaWidth() const 78 | { 79 | int digits = 1; 80 | int max = qMax(1, blockCount()); 81 | while (max >= 10) { 82 | max /= 10; 83 | ++digits; 84 | } 85 | 86 | return 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits; 87 | } 88 | 89 | void 90 | QCodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) 91 | { 92 | setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); 93 | } 94 | 95 | void 96 | QCodeEditor::updateLineNumberArea(QRect rect, int dy) 97 | { 98 | if (dy) 99 | m_lineNumberArea->scroll(0, dy); 100 | else 101 | m_lineNumberArea->update(0, rect.y(), m_lineNumberArea->width(), rect.height()); 102 | 103 | if (rect.contains(viewport()->rect())) 104 | updateLineNumberAreaWidth(0); 105 | } 106 | 107 | void 108 | QCodeEditor::resizeEvent(QResizeEvent* e) 109 | { 110 | QPlainTextEdit::resizeEvent(e); 111 | 112 | const QRect cr = contentsRect(); 113 | m_lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); 114 | } 115 | 116 | void 117 | QCodeEditor::highlightCurrentLine() 118 | { 119 | QList extraSelections; 120 | 121 | if (!isReadOnly()) { 122 | QTextEdit::ExtraSelection selection; 123 | 124 | QColor lineColor = QColor(Qt::yellow).lighter(160); 125 | 126 | selection.format.setBackground(lineColor); 127 | selection.format.setProperty(QTextFormat::FullWidthSelection, true); 128 | selection.cursor = textCursor(); 129 | selection.cursor.clearSelection(); 130 | extraSelections.append(selection); 131 | } 132 | 133 | setExtraSelections(extraSelections); 134 | } 135 | 136 | void 137 | QCodeEditor::lineNumberAreaPaintEvent(QPaintEvent* event) 138 | { 139 | QPainter painter(m_lineNumberArea); 140 | painter.fillRect(event->rect(), QColor(232, 233, 232)); 141 | 142 | QTextBlock block = firstVisibleBlock(); 143 | int blockNumber = block.blockNumber(); 144 | int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top(); 145 | int bottom = top + (int)blockBoundingRect(block).height(); 146 | 147 | while (block.isValid() && top <= event->rect().bottom()) { 148 | if (block.isVisible() && bottom >= event->rect().top()) { 149 | QString number = QString::number(blockNumber + 1); 150 | painter.setPen(QColor(177, 178, 177)); 151 | painter.drawText( 152 | 0, top, m_lineNumberArea->width(), fontMetrics().height(), Qt::AlignRight, number); 153 | } 154 | 155 | block = block.next(); 156 | top = bottom; 157 | bottom = top + (int)blockBoundingRect(block).height(); 158 | ++blockNumber; 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /source/QCodeEditor.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). 4 | ** Contact: http://www.qt-project.org/legal 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** You may use this file under the terms of the BSD license as follows: 10 | ** 11 | ** "Redistribution and use in source and binary forms, with or without 12 | ** modification, are permitted provided that the following conditions are 13 | ** met: 14 | ** * Redistributions of source code must retain the above copyright 15 | ** notice, this list of conditions and the following disclaimer. 16 | ** * Redistributions in binary form must reproduce the above copyright 17 | ** notice, this list of conditions and the following disclaimer in 18 | ** the documentation and/or other materials provided with the 19 | ** distribution. 20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names 21 | ** of its contributors may be used to endorse or promote products derived 22 | ** from this software without specific prior written permission. 23 | ** 24 | ** 25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 36 | ** 37 | ** $QT_END_LICENSE$ 38 | ** 39 | ****************************************************************************/ 40 | 41 | #pragma once 42 | 43 | #include 44 | #include 45 | 46 | class QPaintEvent; 47 | class QResizeEvent; 48 | class QSize; 49 | class QWidget; 50 | 51 | class QCodeEditor : public QPlainTextEdit 52 | { 53 | Q_OBJECT 54 | 55 | public: 56 | QCodeEditor(QWidget* parent = nullptr); 57 | 58 | void lineNumberAreaPaintEvent(QPaintEvent* event); 59 | int lineNumberAreaWidth() const; 60 | 61 | protected: 62 | void resizeEvent(QResizeEvent* event); 63 | 64 | private slots: 65 | void updateLineNumberAreaWidth(int newBlockCount); 66 | void highlightCurrentLine(); 67 | void updateLineNumberArea(QRect, int); 68 | 69 | private: 70 | QWidget* m_lineNumberArea; 71 | }; 72 | -------------------------------------------------------------------------------- /source/QColorButton.cpp: -------------------------------------------------------------------------------- 1 | #include "QColorButton.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | QColorButton::QColorButton(QWidget* parent) 10 | : QPushButton(parent) 11 | { 12 | setFixedSize(70, 32); 13 | } 14 | 15 | QColor 16 | QColorButton::color() const 17 | { 18 | return m_color; 19 | } 20 | 21 | void 22 | QColorButton::setColor(const QColor& color) 23 | { 24 | m_color = color; 25 | 26 | update(); 27 | } 28 | 29 | void 30 | QColorButton::paintEvent(QPaintEvent* event) 31 | { 32 | QPushButton::paintEvent(event); 33 | 34 | QStyleOptionButton option; 35 | option.initFrom(this); 36 | const QRect rect = style()->subElementRect(QStyle::SE_PushButtonContents, &option, this); 37 | QPainter p(this); 38 | p.setPen(Qt::black); 39 | p.setBrush(m_color); 40 | p.drawRect(rect.adjusted(-2, 3, 1, -3)); 41 | } 42 | 43 | void 44 | QColorButton::nextCheckState() 45 | { 46 | QPushButton::nextCheckState(); 47 | 48 | QColor savedColor = m_color; 49 | 50 | std::unique_ptr dialog(new QColorDialog(this)); 51 | dialog->setCurrentColor(m_color); 52 | connect(dialog.get(), SIGNAL(currentColorChanged(QColor)), SLOT(setColor(QColor))); 53 | 54 | if (dialog->exec() == QDialog::Accepted) { 55 | emit selected(m_color); 56 | } else { 57 | setColor(savedColor); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /source/QColorButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class QColorButton : public QPushButton 6 | { 7 | Q_OBJECT 8 | public: 9 | QColorButton(QWidget* parent = nullptr); 10 | 11 | //! Returns the currently selected color. 12 | QColor color() const; 13 | 14 | public slots: 15 | //! Sets the currently selected color. 16 | void setColor(const QColor& color); 17 | 18 | signals: 19 | void selected(const QColor& color); 20 | 21 | protected: 22 | void paintEvent(QPaintEvent*); 23 | void nextCheckState(); 24 | 25 | private: 26 | QColor m_color; 27 | }; 28 | -------------------------------------------------------------------------------- /source/QVectorEdit.cpp: -------------------------------------------------------------------------------- 1 | #include "QVectorEdit.h" 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | QVectorEdit::QVectorEdit(QWidget* parent) 8 | : QWidget(parent) 9 | { 10 | auto layout = new QHBoxLayout(this); 11 | layout->setSpacing(0); 12 | layout->setMargin(0); 13 | 14 | m_x = new QDoubleSpinBox(this); 15 | m_x->setToolTip("X"); 16 | m_x->setMinimumWidth(40); 17 | m_x->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); 18 | m_x->setButtonSymbols(QAbstractSpinBox::NoButtons); 19 | 20 | m_y = new QDoubleSpinBox(this); 21 | m_y->setToolTip("Y"); 22 | m_y->setMinimumWidth(40); 23 | m_y->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); 24 | m_y->setButtonSymbols(QAbstractSpinBox::NoButtons); 25 | 26 | m_z = new QDoubleSpinBox(this); 27 | m_z->setToolTip("Z"); 28 | m_z->setMinimumWidth(40); 29 | m_z->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); 30 | m_z->setButtonSymbols(QAbstractSpinBox::NoButtons); 31 | 32 | m_w = new QDoubleSpinBox(this); 33 | m_w->setToolTip("W"); 34 | m_w->setMinimumWidth(40); 35 | m_w->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); 36 | m_w->setButtonSymbols(QAbstractSpinBox::NoButtons); 37 | 38 | layout->addWidget(m_x); 39 | layout->addWidget(m_y); 40 | layout->addWidget(m_z); 41 | layout->addWidget(m_w); 42 | 43 | setValue(QVector4D(0.f, 0.f, 0.f, 0.f)); 44 | 45 | connect(m_x, SIGNAL(valueChanged(double)), SLOT(onValueChange())); 46 | connect(m_y, SIGNAL(valueChanged(double)), SLOT(onValueChange())); 47 | connect(m_z, SIGNAL(valueChanged(double)), SLOT(onValueChange())); 48 | connect(m_w, SIGNAL(valueChanged(double)), SLOT(onValueChange())); 49 | } 50 | 51 | void 52 | QVectorEdit::setNumFields(int n) 53 | { 54 | m_x->setVisible(n > 0); 55 | m_y->setVisible(n > 1); 56 | m_z->setVisible(n > 2); 57 | m_w->setVisible(n > 3); 58 | } 59 | 60 | void 61 | QVectorEdit::setValue(const QVector4D& vec) 62 | { 63 | blockSignals(true); 64 | m_x->setValue(vec.x()); 65 | m_y->setValue(vec.y()); 66 | m_z->setValue(vec.z()); 67 | m_w->setValue(vec.w()); 68 | blockSignals(false); 69 | } 70 | 71 | QVector4D 72 | QVectorEdit::getValue() const 73 | { 74 | return { float(m_x->value()), float(m_y->value()), float(m_z->value()), float(m_w->value()) }; 75 | } 76 | 77 | QSize 78 | QVectorEdit::sizeHint() const 79 | { 80 | QSize s = m_x->sizeHint(); 81 | return { 4 * 40, s.height() }; 82 | } 83 | 84 | void 85 | QVectorEdit::onValueChange() 86 | { 87 | emit valueChanged(); 88 | } 89 | -------------------------------------------------------------------------------- /source/QVectorEdit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class QDoubleSpinBox; 8 | 9 | class QVectorEdit : public QWidget 10 | { 11 | Q_OBJECT 12 | public: 13 | QVectorEdit(QWidget* parent = nullptr); 14 | 15 | QVector4D getValue() const; 16 | 17 | QSize sizeHint() const; 18 | public slots: 19 | void setNumFields(int n); 20 | void setValue(const QVector4D& vec); 21 | signals: 22 | void valueChanged(); 23 | private slots: 24 | void onValueChange(); 25 | 26 | private: 27 | QDoubleSpinBox* m_x; 28 | QDoubleSpinBox* m_y; 29 | QDoubleSpinBox* m_z; 30 | QDoubleSpinBox* m_w; 31 | }; 32 | -------------------------------------------------------------------------------- /source/SGCanvas.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #include 39 | #include 40 | 41 | #include "SGCanvas.h" 42 | #include "SGCanvasMouseHandler.h" 43 | #include "SGFixedGLState.h" 44 | #include "SGFrame.h" 45 | #include "SGShaderTextWindow.h" 46 | #include "SGSurfaces.h" 47 | #include "SGTextures.h" 48 | 49 | #include 50 | #include 51 | 52 | SGCanvas::SGCanvas(SGFrame* frame) 53 | : QOpenGLWidget(frame) 54 | , CameraZ(-5) 55 | , m_mouse(this) 56 | , m_glCompiled(false) 57 | { 58 | setFocusPolicy(Qt::StrongFocus); 59 | m_mode = GLModeChoiceFixed; 60 | m_frame = frame; 61 | m_modelCurrent = ModelTorus; 62 | 63 | m_models[ModelTorus] = std::make_unique(); 64 | m_models[ModelPlane] = std::make_unique(); 65 | m_models[ModelSphere] = std::make_unique(); 66 | m_models[ModelConic] = std::make_unique(); 67 | m_models[ModelTrefoil] = std::make_unique(); 68 | m_models[ModelKlein] = std::make_unique(); 69 | 70 | for (auto& surface : m_models) { 71 | surface->generate(); 72 | } 73 | } 74 | 75 | SGFixedGLState* 76 | SGCanvas::getGLState() 77 | { 78 | return m_frame->getGLState(); 79 | } 80 | 81 | void 82 | SGCanvas::initializeGL() 83 | { 84 | initializeOpenGLFunctions(); 85 | 86 | // check OpenGl implementation 87 | const int gl_major = context()->format().majorVersion(); 88 | 89 | int gl_numTextures; 90 | glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &gl_numTextures); 91 | if (gl_major < 2.0) { 92 | QString errorString(tr("You must have OpenGL 2.0 compliant drivers to run ShaderGen!")); 93 | QMessageBox::critical(this, tr("OpenGL 2.0 Driver Not Found"), errorString); 94 | 95 | exit(1); 96 | } else if (gl_numTextures < NUM_TEXTURES) { 97 | QString errorString(tr("Your OpenGL Graphics Card Only Supports %1 Texture Units, Some " 98 | "ShaderGen Features May Not Work As Expected!") 99 | .arg(gl_numTextures)); 100 | QMessageBox::critical(this, tr("Insufficient Texture Units"), errorString); 101 | } 102 | 103 | glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 104 | 105 | m_prog.create(); 106 | } 107 | 108 | void 109 | SGCanvas::paintGL() 110 | { 111 | const float aspect = (float)width() / (float)height(); 112 | const float vp = 0.8f; 113 | const float left = -vp; 114 | const float right = vp; 115 | const float bottom = -vp / aspect; 116 | const float top = vp / aspect; 117 | const float zNear = 2; 118 | const float zFar = 10; 119 | const float zoom = m_mouse.getZoom(); 120 | 121 | glMatrixMode(GL_PROJECTION); 122 | glLoadIdentity(); 123 | 124 | const float fov = 45.f; 125 | 126 | m_projection.setToIdentity(); 127 | if (m_frame->isPerspective()) { 128 | m_projection.perspective(fov * zoom, aspect, zNear, zFar); 129 | } else { 130 | m_projection.ortho( 131 | 3 * left * zoom, 3 * right * zoom, 3 * bottom * zoom, 3 * top * zoom, zNear, zFar); 132 | } 133 | glMultMatrixf(m_projection.constData()); 134 | 135 | m_modelView.setToIdentity(); 136 | if (m_frame->isPerspective()) { 137 | m_modelView.translate(0.0f, 0.0f, CameraZ - 1.0f); 138 | } else { 139 | m_modelView.translate(0.0f, 0.0f, CameraZ); 140 | } 141 | m_modelView.rotate(20.0f, 1.0f, 0.0f, 0.0f); 142 | m_modelView *= m_mouse.matrix(); 143 | 144 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 145 | glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 146 | PrintOpenGLError(); 147 | 148 | glMatrixMode(GL_MODELVIEW); 149 | glLoadIdentity(); 150 | 151 | SGFixedGLState* glState = getGLState(); 152 | for (GLint unit = 0; unit < NUM_TEXTURES; unit++) { 153 | const Texture& texture = glState->getTexture(unit); 154 | if (texture.enabled) { 155 | m_frame->getTextures()->bind(texture.currentSelection, unit); 156 | } else { 157 | m_frame->getTextures()->release(unit); 158 | } 159 | } 160 | 161 | PrintOpenGLError(); 162 | 163 | setupFromFixedState(); 164 | 165 | if (m_mode == SGCanvas::GLModeChoiceFixed) { 166 | m_prog.release(); 167 | } else { 168 | m_prog.bind(); 169 | for (int unit = 0; unit < NUM_TEXTURES; unit++) { 170 | m_prog.setUniformValue(qPrintable(QString("texUnit%1").arg(unit)), unit); 171 | } 172 | } 173 | 174 | PrintOpenGLError(); 175 | glPushMatrix(); 176 | 177 | glMultMatrixf(m_modelView.constData()); 178 | drawModel(m_modelCurrent); 179 | PrintOpenGLError(); 180 | glPopMatrix(); 181 | 182 | glFinish(); 183 | PrintOpenGLError(); 184 | } 185 | 186 | void 187 | SGCanvas::resizeGL(int width, int height) 188 | { 189 | glViewport(0, 0, width, height); 190 | } 191 | 192 | void 193 | SGCanvas::setupFromFixedState() 194 | { 195 | PrintOpenGLError(); 196 | SGFixedGLState* glState = getGLState(); 197 | 198 | glEnable(GL_AUTO_NORMAL); 199 | 200 | if (glState->getLightingEnable()) { 201 | glEnable(GL_LIGHTING); 202 | 203 | for (int i = 0; i < 8; i++) { 204 | const Light& light = glState->getLight(i); 205 | if (light.enabled) { 206 | glLight(GL_LIGHT0 + i, GL_POSITION, light.position); 207 | glLight(GL_LIGHT0 + i, GL_AMBIENT, light.ambientColor); 208 | glLight(GL_LIGHT0 + i, GL_DIFFUSE, light.diffuseColor); 209 | glLight(GL_LIGHT0 + i, GL_SPECULAR, light.specularColor); 210 | glLight(GL_LIGHT0 + i, GL_SPOT_DIRECTION, light.spotDirection); 211 | glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, light.spotExponent); 212 | glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, light.spotCutoff); 213 | glLightf(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, light.constantAttenuation); 214 | glLightf(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, light.linearAttenuation); 215 | glLightf(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation); 216 | glEnable(GL_LIGHT0 + i); 217 | } else { 218 | glDisable(GL_LIGHT0 + i); 219 | } 220 | } 221 | } else { 222 | glDisable(GL_LIGHTING); 223 | } 224 | if (glState->getNormalizeEnable()) { 225 | glEnable(GL_NORMALIZE); 226 | } else { 227 | glDisable(GL_NORMALIZE); 228 | } 229 | if (glState->getRescaleNormalEnable()) { 230 | glEnable(GL_RESCALE_NORMAL); 231 | } else { 232 | glDisable(GL_RESCALE_NORMAL); 233 | } 234 | 235 | if (glState->getSeparateSpecularColorEnable()) { 236 | glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); 237 | } else { 238 | glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); 239 | } 240 | 241 | glDepthFunc(GL_LESS); 242 | glEnable(GL_DEPTH_TEST); 243 | const Material& material = glState->getMaterial(); 244 | glMaterial(GL_FRONT, GL_DIFFUSE, material.diffuseColor); 245 | glMaterial(GL_FRONT, GL_SPECULAR, material.specularColor); 246 | glMaterial(GL_FRONT, GL_AMBIENT, material.ambientColor); 247 | glMaterialf(GL_FRONT, GL_SHININESS, material.shininess); 248 | glMaterial(GL_FRONT, GL_EMISSION, material.emissionColor); 249 | 250 | if (glState->getFogEnable()) { 251 | glEnable(GL_FOG); 252 | glFogi(GL_FOG_MODE, glState->getFog().mode); 253 | glFogi(GL_FOG_COORD_SRC, glState->getFog().source); 254 | glFog(GL_FOG_COLOR, glState->getFog().color); 255 | glFogf(GL_FOG_DENSITY, glState->getFog().density); 256 | glFogf(GL_FOG_START, glState->getFog().start); 257 | glFogf(GL_FOG_END, glState->getFog().end); 258 | } else { 259 | glDisable(GL_FOG); 260 | } 261 | } 262 | 263 | void 264 | SGCanvas::drawModel(ModelId id) 265 | { 266 | const TParametricSurface* surface = m_models[id].get(); 267 | 268 | glEnableClientState(GL_NORMAL_ARRAY); 269 | glNormalPointer(GL_FLOAT, sizeof(QVector3D), surface->normals().data()); 270 | 271 | for (int i = 0; i < NUM_TEXTURES; i++) { 272 | glClientActiveTexture(GL_TEXTURE0 + i); 273 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 274 | glTexCoordPointer(2, GL_FLOAT, sizeof(QVector2D), surface->texCoords().data()); 275 | } 276 | glEnableClientState(GL_VERTEX_ARRAY); 277 | glVertexPointer(3, GL_FLOAT, sizeof(QVector3D), surface->vertices().data()); 278 | 279 | for (int i = 0; i < surface->slices(); i++) { 280 | glDrawArrays(GL_TRIANGLE_STRIP, i * surface->slices(), surface->slices()); 281 | } 282 | glDisableClientState(GL_VERTEX_ARRAY); 283 | glDisableClientState(GL_NORMAL_ARRAY); 284 | for (int i = 0; i < NUM_TEXTURES; i++) { 285 | glClientActiveTexture(GL_TEXTURE0 + i); 286 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); 287 | } 288 | } 289 | 290 | QVector3D 291 | SGCanvas::getWorldSpace(int x, int y) 292 | { 293 | QVector3D v(x, height() - 1 - y, CameraZ); 294 | 295 | return v.unproject(m_modelView, m_projection, QRect(0, 0, width(), height())); 296 | } 297 | 298 | QVector2D 299 | SGCanvas::getNormalizedPosition(const QPoint& pos) const 300 | { 301 | return { pos.x() / float(width()), pos.y() / float(height()) }; 302 | } 303 | 304 | void 305 | SGCanvas::keyPressEvent(QKeyEvent* event) 306 | { 307 | switch (event->key()) { 308 | case Qt::Key_PageDown: // page down 309 | m_mouse.setZoom(m_mouse.getZoom() - 0.1f); 310 | break; 311 | case Qt::Key_PageUp: // page up 312 | m_mouse.setZoom(m_mouse.getZoom() + 0.1f); 313 | break; 314 | default: 315 | break; 316 | } 317 | 318 | update(); 319 | } 320 | 321 | void 322 | SGCanvas::mousePressEvent(QMouseEvent* event) 323 | { 324 | m_mouse.onMousePress(event); 325 | update(); 326 | } 327 | 328 | void 329 | SGCanvas::mouseMoveEvent(QMouseEvent* event) 330 | { 331 | m_mouse.onMouseMove(event); 332 | update(); 333 | } 334 | 335 | void 336 | SGCanvas::mouseReleaseEvent(QMouseEvent* /*event*/) 337 | {} 338 | 339 | bool 340 | SGCanvas::linkShaders(const QString& vertexShader, const QString& fragmentShader) 341 | { 342 | if (!m_glCompiled && !compileShaders(vertexShader, fragmentShader)) { 343 | writeMessage(tr("Compilation failed, not attempting link, check shader code")); 344 | return false; 345 | } 346 | 347 | writeMessage(tr("Attempting to link programs....")); 348 | m_prog.link(); 349 | 350 | if (m_prog.log().length() > 0) { 351 | m_frame->getShaderTextWindow()->log(m_prog.log()); 352 | } 353 | 354 | if (!m_prog.isLinked()) { 355 | writeMessage(tr("Error in linking programs!!")); 356 | return false; 357 | } 358 | 359 | writeMessage(tr("Linked programs successfully")); 360 | 361 | return true; 362 | } 363 | 364 | bool 365 | SGCanvas::compileShaders(const QString& vertexShader, const QString& fragmentShader) 366 | { 367 | m_glCompiled = false; 368 | 369 | m_prog.removeAllShaders(); 370 | 371 | if (!m_prog.addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader)) { 372 | writeMessage(tr("Vertex shader failed to compile")); 373 | return false; 374 | } else { 375 | writeMessage(tr("Vertex shader compiled successfully")); 376 | } 377 | if (m_prog.log().length() > 0) { 378 | m_frame->getShaderTextWindow()->log(m_prog.log()); 379 | } 380 | 381 | if (!m_prog.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader)) { 382 | writeMessage(tr("Fragment shader failed to compile")); 383 | return false; 384 | } else { 385 | writeMessage(tr("Fragment shader compiled successfully")); 386 | } 387 | if (m_prog.log().length() > 0) { 388 | m_frame->getShaderTextWindow()->log(m_prog.log()); 389 | } 390 | 391 | m_glCompiled = true; 392 | 393 | return m_glCompiled; 394 | } 395 | 396 | void 397 | SGCanvas::setMode(GLMode m) 398 | { 399 | if (m_mode == m) 400 | return; 401 | 402 | m_mode = m; 403 | if (m_mode == GLModeChoiceShader) { 404 | m_glCompiled = false; 405 | 406 | const QString vert = m_frame->getVertexShader(); 407 | const QString frag = m_frame->getFragmentShader(); 408 | 409 | linkShaders(vert, frag); 410 | } 411 | update(); 412 | } 413 | 414 | void 415 | SGCanvas::writeMessage(const QString& str) 416 | { 417 | m_frame->setStatusText(str); 418 | m_frame->getShaderTextWindow()->log(str); 419 | } 420 | 421 | /****************************************************** 422 | The following functions are used to convert 423 | data back and forth between OpenGL and Qt. 424 | ******************************************************/ 425 | void 426 | SGCanvas::glFog(GLenum pname, const QColor& c) 427 | { 428 | const std::array color = { 429 | (GLfloat)c.redF(), (GLfloat)c.greenF(), (GLfloat)c.blueF(), 1.f 430 | }; 431 | glFogfv(pname, color.data()); 432 | } 433 | 434 | void 435 | SGCanvas::glLight(GLenum light, GLenum pname, const QColor& c) 436 | { 437 | const std::array color = { 438 | (GLfloat)c.redF(), (GLfloat)c.greenF(), (GLfloat)c.blueF(), 1.f 439 | }; 440 | glLightfv(light, pname, color.data()); 441 | } 442 | 443 | void 444 | SGCanvas::glMaterial(GLenum face, GLenum pname, const QColor& c) 445 | { 446 | const std::array color = { 447 | (GLfloat)c.redF(), (GLfloat)c.greenF(), (GLfloat)c.blueF(), 1.f 448 | }; 449 | glMaterialfv(face, pname, color.data()); 450 | } 451 | 452 | void 453 | SGCanvas::glLight(GLenum light, GLenum pname, const QVector3D& v) 454 | { 455 | const std::array vector = { v.x(), v.y(), v.z() }; 456 | glLightfv(light, pname, vector.data()); 457 | } 458 | 459 | void 460 | SGCanvas::glLight(GLenum light, GLenum pname, const QVector4D& v) 461 | { 462 | const std::array vector = { v.x(), v.y(), v.z(), v.w() }; 463 | glLightfv(light, pname, vector.data()); 464 | } 465 | -------------------------------------------------------------------------------- /source/SGCanvas.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #include "SGCanvasMouseHandler.h" 45 | 46 | #include 47 | #include 48 | 49 | class SGFrame; 50 | class SGFixedGLState; 51 | class TParametricSurface; 52 | 53 | class SGCanvas 54 | : public QOpenGLWidget 55 | , protected QOpenGLFunctions_2_1 56 | { 57 | public: 58 | SGCanvas(SGFrame* frame); 59 | ~SGCanvas() = default; 60 | 61 | SGFrame* getFrame() { return m_frame; } 62 | 63 | bool linkShaders(const QString& vertexShader, const QString& fragmentShader); 64 | bool compileShaders(const QString& vertexShader, const QString& fragmentShader); 65 | 66 | // Mode for GL, Fixed or Shader 67 | enum GLMode 68 | { 69 | GLModeChoiceFixed, 70 | GLModeChoiceShader 71 | }; 72 | void setMode(GLMode m); 73 | GLMode getMode() const { return m_mode; } 74 | 75 | const float CameraZ; 76 | 77 | QVector3D getWorldSpace(int x, int y); 78 | 79 | void initializeGL() override; 80 | void paintGL() override; 81 | void resizeGL(int width, int height) override; 82 | 83 | enum ModelId 84 | { 85 | ModelTorus = 0, 86 | ModelPlane, 87 | ModelSphere, 88 | ModelConic, 89 | ModelTrefoil, 90 | ModelKlein 91 | }; 92 | void setModel(ModelId id) { m_modelCurrent = id; } 93 | 94 | QVector2D getNormalizedPosition(const QPoint& pos) const; 95 | 96 | protected: 97 | void keyPressEvent(QKeyEvent* event) override; 98 | void mousePressEvent(QMouseEvent* event) override; 99 | void mouseMoveEvent(QMouseEvent* event) override; 100 | void mouseReleaseEvent(QMouseEvent* event) override; 101 | 102 | private: 103 | SGFixedGLState* getGLState(); 104 | 105 | GLMode m_mode; 106 | SGCanvasMouseHandler m_mouse; 107 | ModelId m_modelCurrent; 108 | std::array, 6> m_models; 109 | SGFrame* m_frame; 110 | 111 | QMatrix4x4 m_modelView; 112 | QMatrix4x4 m_projection; 113 | 114 | bool m_glCompiled; 115 | QOpenGLShaderProgram m_prog; 116 | 117 | void setupFromFixedState(); 118 | void writeMessage(const QString& str); 119 | void drawModel(ModelId id); 120 | 121 | void glFog(GLenum pname, const QColor& c); 122 | void glLight(GLenum light, GLenum pname, const QColor& c); 123 | void glMaterial(GLenum face, GLenum pname, const QColor& c); 124 | void glLight(GLenum light, GLenum pname, const QVector3D& v); 125 | void glLight(GLenum light, GLenum pname, const QVector4D& v); 126 | }; 127 | -------------------------------------------------------------------------------- /source/SGCanvasMouseHandler.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #include 39 | #include 40 | 41 | #include "SGCanvas.h" 42 | #include "SGCanvasMouseHandler.h" 43 | #include "SGFrame.h" 44 | 45 | #define _USE_MATH_DEFINES 46 | #include 47 | #include 48 | 49 | QVector3D 50 | sphereSheetProjector(const QVector2D& pos) 51 | { 52 | QVector3D rayOrigin(pos.x() - 0.5f, 0.5f - pos.y(), -0.5f); 53 | const QVector3D rayDirection(0, 0, 1); 54 | const QVector3D sphereOrigin(0, 0, 0); 55 | const float sphereRadius = 0.35f; 56 | 57 | // ray / sphere intersection 58 | const QVector3D r_to_s = rayOrigin - sphereOrigin; 59 | 60 | // Compute A, B and C coefficients 61 | const float A = rayDirection.lengthSquared(); 62 | const float B = 2.0f * QVector3D::dotProduct(r_to_s, rayDirection); 63 | const float C = r_to_s.lengthSquared() - sphereRadius * sphereRadius; 64 | 65 | // Find discriminant 66 | const float disc = B * B - 4.0 * A * C; 67 | 68 | // if discriminant is negative there are no real roots 69 | if (disc >= 0.0) { 70 | const float t0 = (-B + std::sqrt(disc)) / (2.0 * A); 71 | if (t0 > 0) { 72 | rayOrigin = rayOrigin + t0 * rayDirection; 73 | } 74 | } 75 | 76 | // intersection with the sheet 77 | const QVector3D planeHit = 78 | rayOrigin + rayDirection * rayOrigin.distanceToPlane(sphereOrigin, -rayDirection); 79 | 80 | // distance from plane hit point to plane center in the projector 81 | const float planarDist = (planeHit - sphereOrigin).length(); 82 | 83 | // let sphere and hyperbolic sheet meet at 45° 84 | const float meetDist = sphereRadius * (float)std::cos(M_PI / 4.0); 85 | 86 | if (planarDist < meetDist) 87 | return rayOrigin; 88 | 89 | // By Pythagoras' we know that the value of the sphere at 45° 90 | // angle from the groundplane will be (radius^2 * 0.5). 91 | const float v = (sphereRadius * sphereRadius) * 0.5f; 92 | 93 | // A hyperbolic function is given by y = 1 / x, where x in our 94 | // case is the "radial" distance from the plane centerpoint to the 95 | // plane intersection point. 96 | const float hyperbval = (1.0f / planarDist) * v; 97 | 98 | return planeHit + QVector3D(0.0f, 0.0f, hyperbval); 99 | } 100 | 101 | SGCanvasMouseHandler::SGCanvasMouseHandler(SGCanvas* canvas1) 102 | : m_canvas(canvas1) 103 | , m_startZoom(1.f) 104 | { 105 | m_zoom = 0.5f; 106 | } 107 | 108 | void 109 | SGCanvasMouseHandler::onMousePress(QMouseEvent* event) 110 | { 111 | m_vStart = event->pos(); 112 | m_mStart = m_xform; 113 | m_startZoom = m_zoom; 114 | } 115 | 116 | void 117 | SGCanvasMouseHandler::onMouseMove(QMouseEvent* event) 118 | { 119 | if ((event->buttons() & Qt::RightButton) || 120 | ((event->buttons() & Qt::LeftButton) && (event->modifiers() & Qt::ControlModifier))) { 121 | const QVector3D lstart = m_canvas->getWorldSpace(m_vStart.x(), m_vStart.y()); 122 | const QVector3D lend = m_canvas->getWorldSpace(event->x(), event->y()); 123 | const float delta = lend.y() - lstart.y(); 124 | if (delta) { 125 | m_zoom = m_startZoom + delta; 126 | } 127 | } else { 128 | if (event->buttons() & Qt::LeftButton) { 129 | const QVector3D lstart = 130 | sphereSheetProjector(m_canvas->getNormalizedPosition(m_vStart)); 131 | const QVector3D lend = 132 | sphereSheetProjector(m_canvas->getNormalizedPosition(event->pos())); 133 | const QQuaternion rotation = QQuaternion::rotationTo(lstart, lend); 134 | 135 | m_xform.setToIdentity(); 136 | m_xform.rotate(rotation); 137 | m_xform *= m_mStart; 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /source/SGCanvasMouseHandler.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | 43 | class SGCanvas; 44 | class QMouseEvent; 45 | 46 | class SGCanvasMouseHandler 47 | { 48 | public: 49 | SGCanvasMouseHandler(SGCanvas* canvas); 50 | void onMousePress(QMouseEvent* event); 51 | void onMouseMove(QMouseEvent* event); 52 | const QMatrix4x4& matrix() const { return m_xform; } 53 | float getZoom() const { return m_zoom; } 54 | void setZoom(float value) { m_zoom = value; } 55 | private: 56 | SGCanvas* m_canvas; 57 | 58 | QPoint m_vStart; 59 | float m_startZoom; 60 | QMatrix4x4 m_mStart; 61 | 62 | float m_zoom; 63 | QMatrix4x4 m_xform; 64 | }; 65 | -------------------------------------------------------------------------------- /source/SGFixedGLState.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #include "SGFixedGLState.h" 39 | #include "globals.h" 40 | #include 41 | #include 42 | #include 43 | 44 | void 45 | SGFixedGLState::init() 46 | { 47 | for (int i = 0; i < NUM_LIGHTS; i++) { 48 | initLight(i); 49 | } 50 | 51 | for (int i = 0; i < NUM_LIGHTS_ENABLED_AT_START; i++) { 52 | m_light[i].enabled = true; 53 | } 54 | 55 | for (int i = 0; i < NUM_TEXTURES; i++) { 56 | initTexture(i); 57 | } 58 | 59 | initMaterial(); 60 | initFog(); 61 | 62 | setLightingEnable(true); 63 | setTwoSidedLightingEnable(false); 64 | setFogEnable(false); 65 | setSeparateSpecularColorEnable(false); 66 | setLocalViewerLightingEnable(false); 67 | 68 | setTextureEnable(false); 69 | setTexGenEnable(false); 70 | setNormalizeEnable(true); 71 | setRescaleNormalEnable(false); 72 | } 73 | 74 | void 75 | SGFixedGLState::initLight(int num) 76 | { 77 | Light& light = m_light[num]; 78 | 79 | light.enabled = false; 80 | 81 | switch (num) { 82 | case 1: 83 | light.position = DEFAULT_LIGHT_POSITION_ONE; 84 | light.ambientColor = DEFAULT_LIGHT_AMBIENT_COLOR_ONE; 85 | light.diffuseColor = DEFAULT_LIGHT_DIFFUSE_COLOR_ONE; 86 | light.specularColor = DEFAULT_LIGHT_SPECULAR_COLOR_ONE; 87 | break; 88 | case 2: 89 | light.position = DEFAULT_LIGHT_POSITION_TWO; 90 | light.ambientColor = DEFAULT_LIGHT_AMBIENT_COLOR_TWO; 91 | light.diffuseColor = DEFAULT_LIGHT_DIFFUSE_COLOR_TWO; 92 | light.specularColor = DEFAULT_LIGHT_SPECULAR_COLOR_TWO; 93 | break; 94 | case 3: 95 | light.position = DEFAULT_LIGHT_POSITION_THREE; 96 | light.ambientColor = DEFAULT_LIGHT_AMBIENT_COLOR_THREE; 97 | light.diffuseColor = DEFAULT_LIGHT_DIFFUSE_COLOR_THREE; 98 | light.specularColor = DEFAULT_LIGHT_SPECULAR_COLOR_THREE; 99 | break; 100 | default: 101 | light.position = DEFAULT_LIGHT_POSITION_OTHER; 102 | light.ambientColor = DEFAULT_LIGHT_AMBIENT_COLOR_OTHER; 103 | light.diffuseColor = DEFAULT_LIGHT_DIFFUSE_COLOR_OTHER; 104 | light.specularColor = DEFAULT_LIGHT_SPECULAR_COLOR_OTHER; 105 | break; 106 | } 107 | light.spotDirection = DEFAULT_LIGHT_SPOT_DIRECTION; 108 | 109 | light.spotCutoff = DEFAULT_SPOT_CUT; 110 | light.spotExponent = DEFAULT_SPOT_EXP; 111 | light.constantAttenuation = DEFAULT_LIGHT_CONST_ATTEN; 112 | light.linearAttenuation = DEFAULT_LIGHT_LINEAR_ATTEN; 113 | light.quadraticAttenuation = DEFAULT_LIGHT_QUAD_ATTEN; 114 | } 115 | 116 | void 117 | SGFixedGLState::initMaterial() 118 | { 119 | m_material.ambientColor = DEFAULT_MATERIAL_AMBIENT_COLOR; 120 | m_material.diffuseColor = DEFAULT_MATERIAL_DIFFUSE_COLOR; 121 | m_material.specularColor = DEFAULT_MATERIAL_SPECULAR_COLOR; 122 | 123 | m_material.shininess = DEFAULT_MATERIAL_SHININESS; 124 | 125 | m_material.emissionColor = DEFAULT_MATERIAL_EMISSION_COLOR; 126 | } 127 | 128 | void 129 | SGFixedGLState::initFog() 130 | { 131 | m_fog.mode = GL_LINEAR; 132 | m_fog.source = GL_FRAGMENT_DEPTH; 133 | 134 | m_fog.density = DEFAULT_FOG_DENSITY; 135 | m_fog.start = DEFAULT_FOG_START; 136 | m_fog.end = DEFAULT_FOG_END; 137 | 138 | m_fog.color = DEFAULT_FOG_COLOR; 139 | } 140 | 141 | void 142 | SGFixedGLState::initTexture(int num) 143 | { 144 | Texture& texture = m_texture[num]; 145 | 146 | texture.enabled = false; 147 | 148 | texture.texGen = false; 149 | texture.applicationMethod = GL_MODULATE; 150 | texture.coordinateGeneration = GL_OBJECT_LINEAR; 151 | texture.combineMode = GL_MODULATE; 152 | texture.combineScale = DEFAULT_COMBINE_RGB_SCALE; 153 | texture.combineSource0 = GL_TEXTURE; 154 | texture.combineSource1 = GL_PREVIOUS; 155 | texture.combineSource2 = GL_CONSTANT; 156 | texture.combineOperand0 = GL_SRC_COLOR; 157 | texture.combineOperand1 = GL_SRC_COLOR; 158 | texture.combineOperand2 = GL_SRC_COLOR; 159 | texture.currentSelection = num; 160 | texture.texEnvColor = DEFAULT_TEX_ENV_COLOR; 161 | texture.eyePlaneCoeffS = DEFAULT_EYE_PLANE_COEFF_S; 162 | texture.eyePlaneCoeffT = DEFAULT_EYE_PLANE_COEFF_T; 163 | texture.objectPlaneCoeffS = DEFAULT_OBJ_PLANE_COEFF_S; 164 | texture.objectPlaneCoeffT = DEFAULT_OBJ_PLANE_COEFF_T; 165 | } 166 | 167 | static QJsonArray 168 | fromVector3D(const QVector3D& vec) 169 | { 170 | QJsonArray array; 171 | array.append(vec.x()); 172 | array.append(vec.y()); 173 | array.append(vec.z()); 174 | return array; 175 | } 176 | 177 | static QJsonArray 178 | fromVector4D(const QVector4D& vec) 179 | { 180 | QJsonArray array; 181 | array.append(vec.x()); 182 | array.append(vec.y()); 183 | array.append(vec.z()); 184 | array.append(vec.w()); 185 | return array; 186 | } 187 | 188 | static QVector3D 189 | toVector3D(const QJsonValueRef& value) 190 | { 191 | QJsonArray array = value.toArray(); 192 | return { float(array[0].toDouble()), float(array[1].toDouble()), float(array[2].toDouble()) }; 193 | } 194 | 195 | static QVector4D 196 | toVector4D(const QJsonValueRef& value) 197 | { 198 | QJsonArray array = value.toArray(); 199 | return { float(array[0].toDouble()), 200 | float(array[1].toDouble()), 201 | float(array[2].toDouble()), 202 | float(array[3].toDouble()) }; 203 | } 204 | 205 | void 206 | SGFixedGLState::read(const QJsonObject& json) 207 | { 208 | m_fogEnable = json["fogEnable"].toBool(); 209 | m_lightingEnable = json["lightingEnable"].toBool(); 210 | m_twoSidedLightingEnable = json["twoSidedLightingEnable"].toBool(); 211 | m_localViewerLightingEnable = json["localViewerLightingEnable"].toBool(); 212 | m_normalizeEnable = json["normalizeEnable"].toBool(); 213 | m_rescaleNormalEnable = json["rescaleNormal"].toBool(); 214 | m_twoSidedLightingEnable = json["twoSidedLightingEnable"].toBool(); 215 | m_textureEnable = json["textureEnable"].toBool(); 216 | m_texGenEnable = json["texGenEnable"].toBool(); 217 | m_separateSpecularColorEnable = json["separateSpecularColorEnable"].toBool(); 218 | 219 | QJsonArray lightArray = json["lights"].toArray(); 220 | for (int i = 0; i < lightArray.size(); ++i) { 221 | QJsonObject lightObject = lightArray[i].toObject(); 222 | Light& light = m_light[i]; 223 | 224 | light.enabled = lightObject["enabled"].toBool(); 225 | 226 | light.spotExponent = lightObject["spotExponent"].toDouble(); 227 | light.spotCutoff = lightObject["spotCutoff"].toDouble(); 228 | light.constantAttenuation = lightObject["constantAttenuation"].toDouble(); 229 | light.linearAttenuation = lightObject["linearAttenuation"].toDouble(); 230 | light.quadraticAttenuation = lightObject["quadraticAttenuation"].toDouble(); 231 | 232 | light.spotDirection = toVector3D(lightObject["spotDirectionVector"]); 233 | light.position = toVector4D(lightObject["positionVector"]); 234 | light.ambientColor.setNamedColor(lightObject["ambientColorVector"].toString()); 235 | light.diffuseColor.setNamedColor(lightObject["diffuseColorVector"].toString()); 236 | light.specularColor.setNamedColor(lightObject["specularColorVector"].toString()); 237 | } 238 | 239 | QJsonArray textureArray = json["textures"].toArray(); 240 | for (int i = 0; i < textureArray.size(); ++i) { 241 | QJsonObject textureObject = textureArray[i].toObject(); 242 | Texture& texture = m_texture[i]; 243 | texture.enabled = textureObject["textureEnabled"].toBool(); 244 | texture.texGen = textureObject["texGen"].toBool(); 245 | texture.eyePlaneCoeffS = toVector4D(textureObject["eyePlaneCoeffS"]); 246 | texture.eyePlaneCoeffT = toVector4D(textureObject["eyePlaneCoeffT"]); 247 | texture.objectPlaneCoeffS = toVector4D(textureObject["objectPlaneCoeffS"]); 248 | texture.objectPlaneCoeffT = toVector4D(textureObject["objectPlaneCoeffT"]); 249 | texture.texEnvColor.setNamedColor(textureObject["texEnvColor"].toString()); 250 | texture.applicationMethod = textureObject["applicationMethod"].toInt(); 251 | texture.coordinateGeneration = textureObject["coordinateGeneration"].toInt(); 252 | texture.currentSelection = textureObject["currentSelection"].toInt(); 253 | texture.combineScale = textureObject["combineScale"].toDouble(); 254 | texture.combineMode = textureObject["combineMode"].toInt(); 255 | texture.combineSource0 = textureObject["combineSource0"].toInt(); 256 | texture.combineSource1 = textureObject["combineSource1"].toInt(); 257 | texture.combineSource2 = textureObject["combineSource2"].toInt(); 258 | texture.combineOperand0 = textureObject["combineOperand0"].toInt(); 259 | texture.combineOperand1 = textureObject["combineOperand1"].toInt(); 260 | texture.combineOperand2 = textureObject["combineOperand2"].toInt(); 261 | } 262 | 263 | QJsonObject materialObject = json["material"].toObject(); 264 | m_material.diffuseColor.setNamedColor(materialObject["diffuseColor"].toString()); 265 | m_material.ambientColor.setNamedColor(materialObject["ambientColor"].toString()); 266 | m_material.specularColor.setNamedColor(materialObject["specularColor"].toString()); 267 | m_material.emissionColor.setNamedColor(materialObject["emissionColor"].toString()); 268 | m_material.shininess = materialObject["shininess"].toDouble(); 269 | m_material.faceSelection = materialObject["faceSelection"].toInt(); 270 | 271 | QJsonObject fogObject = json["fog"].toObject(); 272 | m_fog.start = fogObject["start"].toDouble(); 273 | m_fog.end = fogObject["end"].toDouble(); 274 | m_fog.density = fogObject["density"].toDouble(); 275 | m_fog.color.setNamedColor(fogObject["colorVector"].toString()); 276 | m_fog.mode = fogObject["mode"].toInt(); 277 | m_fog.source = fogObject["source"].toInt(); 278 | } 279 | 280 | void 281 | SGFixedGLState::write(QJsonObject& json) const 282 | { 283 | json["fogEnable"] = m_fogEnable; 284 | json["lightingEnable"] = m_lightingEnable; 285 | json["twoSidedLightingEnable"] = m_twoSidedLightingEnable; 286 | json["localViewerLightingEnable"] = m_localViewerLightingEnable; 287 | json["normalizeEnable"] = m_normalizeEnable; 288 | json["rescaleNormalEnable"] = m_rescaleNormalEnable; 289 | json["twoSidedLightingEnable"] = m_twoSidedLightingEnable, 290 | json["textureEnable"] = m_textureEnable; 291 | json["texGenEnable"] = m_texGenEnable; 292 | json["separateSpecularColorEnable"] = m_separateSpecularColorEnable; 293 | 294 | QJsonArray lightArray; 295 | for (const auto& light : m_light) { 296 | QJsonObject lightObject; 297 | lightObject["enabled"] = light.enabled; 298 | 299 | lightObject["spotExponent"] = light.spotExponent; 300 | lightObject["spotCutoff"] = light.spotCutoff; 301 | lightObject["constantAttenuation"] = light.constantAttenuation; 302 | lightObject["linearAttenuation"] = light.linearAttenuation; 303 | lightObject["quadraticAttenuation"] = light.quadraticAttenuation; 304 | 305 | lightObject["spotDirectionVector"] = fromVector3D(light.spotDirection); 306 | lightObject["positionVector"] = fromVector4D(light.position); 307 | lightObject["ambientColorVector"] = light.ambientColor.name(); 308 | lightObject["diffuseColorVector"] = light.diffuseColor.name(); 309 | lightObject["specularColorVector"] = light.specularColor.name(); 310 | lightArray.append(lightObject); 311 | } 312 | json["lights"] = lightArray; 313 | 314 | QJsonArray textureArray; 315 | for (const auto& texture : m_texture) { 316 | QJsonObject textureObject; 317 | textureObject["textureEnabled"] = texture.enabled; 318 | textureObject["texGen"] = texture.texGen; 319 | textureObject["eyePlaneCoeffS"] = fromVector4D(texture.eyePlaneCoeffS); 320 | textureObject["eyePlaneCoeffT"] = fromVector4D(texture.eyePlaneCoeffT); 321 | textureObject["objectPlaneCoeffS"] = fromVector4D(texture.objectPlaneCoeffS); 322 | textureObject["objectPlaneCoeffT"] = fromVector4D(texture.objectPlaneCoeffT); 323 | textureObject["texEnvColor"] = texture.texEnvColor.name(); 324 | textureObject["applicationMethod"] = (int)texture.applicationMethod; 325 | textureObject["coordinateGeneration"] = (int)texture.coordinateGeneration; 326 | textureObject["currentSelection"] = texture.currentSelection; 327 | textureObject["combineScale"] = texture.combineScale; 328 | textureObject["combineMode"] = (int)texture.combineMode; 329 | textureObject["combineSource0"] = (int)texture.combineSource0; 330 | textureObject["combineSource1"] = (int)texture.combineSource1; 331 | textureObject["combineSource2"] = (int)texture.combineSource2; 332 | textureObject["combineOperand0"] = (int)texture.combineOperand0; 333 | textureObject["combineOperand1"] = (int)texture.combineOperand1; 334 | textureObject["combineOperand2"] = (int)texture.combineOperand2; 335 | textureArray.append(textureObject); 336 | } 337 | json["textures"] = textureArray; 338 | 339 | QJsonObject materialObject; 340 | materialObject["diffuseColor"] = m_material.diffuseColor.name(); 341 | materialObject["ambientColor"] = m_material.ambientColor.name(); 342 | materialObject["specularColor"] = m_material.specularColor.name(); 343 | materialObject["emissionColor"] = m_material.emissionColor.name(); 344 | materialObject["shininess"] = m_material.shininess; 345 | materialObject["faceSelection"] = (int)m_material.faceSelection; 346 | json["material"] = materialObject; 347 | 348 | QJsonObject fogObject; 349 | fogObject["start"] = m_fog.start; 350 | fogObject["end"] = m_fog.end; 351 | fogObject["density"] = m_fog.density; 352 | fogObject["colorVector"] = m_fog.color.name(); 353 | fogObject["mode"] = (int)m_fog.mode; 354 | fogObject["source"] = (int)m_fog.source; 355 | json["fog"] = fogObject; 356 | } 357 | -------------------------------------------------------------------------------- /source/SGFixedGLState.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include "globals.h" 46 | 47 | struct Light 48 | { 49 | bool enabled; 50 | 51 | float spotExponent; 52 | float spotCutoff; 53 | float constantAttenuation; 54 | float linearAttenuation; 55 | float quadraticAttenuation; 56 | 57 | QVector3D spotDirection; 58 | QVector4D position; 59 | QColor ambientColor; 60 | QColor diffuseColor; 61 | QColor specularColor; 62 | }; 63 | 64 | struct Material 65 | { 66 | QColor diffuseColor; 67 | QColor ambientColor; 68 | QColor specularColor; 69 | QColor emissionColor; 70 | float shininess; 71 | int faceSelection; 72 | }; 73 | 74 | struct Fog 75 | { 76 | float start, end, density; 77 | QColor color; 78 | int mode; 79 | int source; 80 | }; 81 | 82 | struct Texture 83 | { 84 | bool enabled; 85 | 86 | bool texGen; 87 | 88 | QVector4D eyePlaneCoeffS; 89 | QVector4D eyePlaneCoeffT; 90 | 91 | QVector4D objectPlaneCoeffS; 92 | QVector4D objectPlaneCoeffT; 93 | 94 | QColor texEnvColor; 95 | 96 | int applicationMethod; 97 | int coordinateGeneration; 98 | 99 | int currentSelection; 100 | 101 | float combineScale; 102 | 103 | int combineMode; 104 | 105 | int combineSource0; 106 | int combineSource1; 107 | int combineSource2; 108 | int combineOperand0; 109 | int combineOperand1; 110 | int combineOperand2; 111 | }; 112 | 113 | // Wrapper 114 | class SGFixedGLState 115 | { 116 | 117 | public: 118 | SGFixedGLState() { init(); } 119 | ~SGFixedGLState() = default; 120 | void init(); 121 | 122 | Light& getLight(int num) { return m_light[num]; } 123 | Material& getMaterial() { return m_material; } 124 | Fog& getFog() { return m_fog; } 125 | Texture& getTexture(int num) { return m_texture[num]; } 126 | 127 | bool getLightingEnable() const { return m_lightingEnable; } 128 | bool getTwoSidedLightingEnable() const { return m_twoSidedLightingEnable; } 129 | bool getLocalViewerLightingEnable() const { return m_localViewerLightingEnable; } 130 | bool getFogEnable() const { return m_fogEnable; } 131 | bool getNormalizeEnable() const { return m_normalizeEnable; } 132 | bool getRescaleNormalEnable() const { return m_rescaleNormalEnable; } 133 | bool getSeparateSpecularColorEnable() const { return m_separateSpecularColorEnable; } 134 | bool getTextureEnable() const { return m_textureEnable; } 135 | 136 | void setLightingEnable(bool en) { m_lightingEnable = en; } 137 | void setTwoSidedLightingEnable(bool en) { m_twoSidedLightingEnable = en; } 138 | void setLocalViewerLightingEnable(bool en) { m_localViewerLightingEnable = en; } 139 | void setFogEnable(bool en) { m_fogEnable = en; } 140 | void setNormalizeEnable(bool en) { m_normalizeEnable = en; } 141 | void setRescaleNormalEnable(bool en) { m_rescaleNormalEnable = en; } 142 | void setSeparateSpecularColorEnable(bool en) { m_separateSpecularColorEnable = en; } 143 | void setTextureEnable(bool en) { m_textureEnable = en; } 144 | 145 | bool getTexGenEnable() const { return m_texGenEnable; } 146 | 147 | void setTexGenEnable(bool en) { m_texGenEnable = en; } 148 | 149 | void read(const QJsonObject& json); 150 | void write(QJsonObject& json) const; 151 | 152 | private: 153 | void initLight(int num); 154 | void initMaterial(); 155 | void initFog(); 156 | void initTexture(int num); 157 | 158 | bool m_fogEnable, m_lightingEnable, m_normalizeEnable, m_twoSidedLightingEnable, 159 | m_textureEnable, m_texGenEnable, m_separateSpecularColorEnable, m_rescaleNormalEnable, 160 | m_localViewerLightingEnable; 161 | Light m_light[NUM_LIGHTS]; 162 | Texture m_texture[NUM_TEXTURES]; 163 | Material m_material; 164 | Fog m_fog; 165 | }; 166 | -------------------------------------------------------------------------------- /source/SGFrame.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "SGCanvas.h" 16 | #include "SGFixedGLState.h" 17 | #include "SGFrame.h" 18 | #include "SGOglNotebook.h" 19 | #include "SGShaderTextWindow.h" 20 | #include "SGTextures.h" 21 | 22 | static SGFrame* sgframe_instance = nullptr; 23 | 24 | SGFrame::SGFrame(const QString& title) 25 | { 26 | setWindowTitle(title); 27 | 28 | m_glState = std::make_unique(); 29 | m_textures = std::make_unique(this, m_glState.get()); 30 | m_shaderGen = std::make_unique(m_glState.get()); 31 | 32 | createActions(); 33 | createMenus(); 34 | createStatusBar(); 35 | 36 | m_oglNotebook = new SGOglNotebook(m_glState.get(), this); 37 | m_oglNotebook->resize(800, 300); 38 | connect(m_oglNotebook, SIGNAL(valueChanged()), SLOT(setFixedGLMode())); 39 | 40 | auto canvasWrapper = new QFrame(this); 41 | auto canvasWrapperLayout = new QVBoxLayout(canvasWrapper); 42 | 43 | m_canvas = new SGCanvas(this); 44 | m_canvas->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 45 | 46 | auto gb = new QGroupBox(tr("Select GL Mode"), this); 47 | gb->setLayout(new QHBoxLayout); 48 | auto fixed = new QRadioButton(tr("FIXED FUNCTIONALITY MODE"), gb); 49 | fixed->setChecked(true); 50 | auto shader = new QRadioButton(tr("EQUIVALENT SHADER MODE "), gb); 51 | gb->layout()->addWidget(fixed); 52 | gb->layout()->addWidget(shader); 53 | 54 | m_glModeChoice = new QButtonGroup(this); 55 | m_glModeChoice->addButton(fixed, 0); 56 | m_glModeChoice->addButton(shader, 1); 57 | connect(m_glModeChoice, SIGNAL(buttonClicked(int)), SLOT(onGLModeChanged(int))); 58 | 59 | canvasWrapperLayout->addWidget(gb); 60 | canvasWrapperLayout->addWidget(m_canvas); 61 | canvasWrapper->resize(400, 350); 62 | 63 | m_shaderText = new SGShaderTextWindow(this); 64 | m_shaderText->resize(450, 400); 65 | 66 | m_topSizer = new QSplitter(Qt::Vertical); 67 | m_horizSizer = new QSplitter(Qt::Horizontal); 68 | 69 | m_horizSizer->addWidget(canvasWrapper); 70 | m_horizSizer->addWidget(m_shaderText); 71 | 72 | m_topSizer->addWidget(m_horizSizer); 73 | m_topSizer->addWidget(m_oglNotebook); 74 | 75 | setCentralWidget(m_topSizer); 76 | 77 | sgframe_instance = this; 78 | } 79 | 80 | SGFrame::~SGFrame() 81 | { 82 | sgframe_instance = nullptr; 83 | } 84 | 85 | void 86 | SGFrame::createActions() 87 | { 88 | m_openAct = new QAction(tr("&Open..."), this); 89 | m_openAct->setShortcuts(QKeySequence::Open); 90 | m_openAct->setStatusTip(tr("Open an existing file")); 91 | connect(m_openAct, SIGNAL(triggered()), this, SLOT(open())); 92 | 93 | m_saveAsAct = new QAction(tr("Save &As..."), this); 94 | m_saveAsAct->setShortcuts(QKeySequence::SaveAs); 95 | m_saveAsAct->setStatusTip(tr("Save the document under a new name")); 96 | connect(m_saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); 97 | 98 | m_exitAct = new QAction(tr("E&xit"), this); 99 | m_exitAct->setShortcuts(QKeySequence::Quit); 100 | m_exitAct->setStatusTip(tr("Exit the application")); 101 | connect(m_exitAct, SIGNAL(triggered()), this, SLOT(close())); 102 | 103 | m_perspAct = new QAction(tr("Perspective"), this); 104 | m_perspAct->setCheckable(true); 105 | m_perspAct->setChecked(true); 106 | connect(m_perspAct, SIGNAL(triggered()), SLOT(viewActionTriggered())); 107 | 108 | m_switchGLModeAct = new QAction(tr("Switch GL mode"), this); 109 | m_switchGLModeAct->setShortcut(Qt::Key_F7); 110 | connect(m_switchGLModeAct, SIGNAL(triggered()), SLOT(switchGLModeTriggered())); 111 | 112 | m_torusAct = new QAction(tr("Torus"), this); 113 | m_torusAct->setCheckable(true); 114 | m_torusAct->setChecked(true); 115 | 116 | m_sphereAct = new QAction(tr("Sphere"), this); 117 | m_sphereAct->setCheckable(true); 118 | 119 | m_trefoilAct = new QAction(tr("Trefoil"), this); 120 | m_trefoilAct->setCheckable(true); 121 | 122 | m_kleinAct = new QAction(tr("Klein"), this); 123 | m_kleinAct->setCheckable(true); 124 | 125 | m_conicAct = new QAction(tr("Conic"), this); 126 | m_conicAct->setCheckable(true); 127 | 128 | m_planeAct = new QAction(tr("Plane"), this); 129 | m_planeAct->setCheckable(true); 130 | 131 | auto modelGroup = new QActionGroup(this); 132 | modelGroup->addAction(m_torusAct); 133 | modelGroup->addAction(m_sphereAct); 134 | modelGroup->addAction(m_trefoilAct); 135 | modelGroup->addAction(m_kleinAct); 136 | modelGroup->addAction(m_conicAct); 137 | modelGroup->addAction(m_planeAct); 138 | connect(modelGroup, SIGNAL(triggered(QAction*)), SLOT(modelActionTriggered(QAction*))); 139 | 140 | m_aboutAct = new QAction(tr("&About"), this); 141 | m_aboutAct->setStatusTip(tr("Show the application's About box")); 142 | connect(m_aboutAct, SIGNAL(triggered()), this, SLOT(about())); 143 | 144 | m_helpAct = new QAction(tr("Help"), this); 145 | m_helpAct->setStatusTip(tr("Show the help")); 146 | connect(m_helpAct, SIGNAL(triggered()), this, SLOT(help())); 147 | } 148 | 149 | void 150 | SGFrame::createMenus() 151 | { 152 | m_fileMenu = menuBar()->addMenu(tr("&File")); 153 | m_fileMenu->addAction(m_openAct); 154 | m_fileMenu->addAction(m_saveAsAct); 155 | m_fileMenu->addSeparator(); 156 | m_fileMenu->addAction(m_exitAct); 157 | 158 | menuBar()->addSeparator(); 159 | 160 | m_viewMenu = menuBar()->addMenu(tr("&View")); 161 | m_viewMenu->addAction(m_perspAct); 162 | m_viewMenu->addSeparator(); 163 | m_viewMenu->addAction(m_switchGLModeAct); 164 | 165 | m_modelMenu = menuBar()->addMenu(tr("&Model")); 166 | m_modelMenu->addAction(m_torusAct); 167 | m_modelMenu->addAction(m_sphereAct); 168 | m_modelMenu->addAction(m_trefoilAct); 169 | m_modelMenu->addAction(m_kleinAct); 170 | m_modelMenu->addAction(m_conicAct); 171 | m_modelMenu->addAction(m_planeAct); 172 | 173 | m_helpMenu = menuBar()->addMenu(tr("&Help")); 174 | m_helpMenu->addAction(m_aboutAct); 175 | m_helpMenu->addAction(m_helpAct); 176 | } 177 | 178 | void 179 | SGFrame::createStatusBar() 180 | { 181 | statusBar()->showMessage(windowTitle()); 182 | } 183 | 184 | void 185 | SGFrame::setCanvasMode(SGCanvas::GLMode a) 186 | { 187 | if (a == SGCanvas::GLModeChoiceFixed) { 188 | m_glModeChoice->button(0)->setChecked(true); 189 | } else { 190 | m_glModeChoice->button(1)->setChecked(true); 191 | } 192 | const QString vert = getVertexShader(); 193 | const QString frag = getFragmentShader(); 194 | 195 | getShaderTextWindow()->setFragmentShaderText(frag); 196 | getShaderTextWindow()->setVertexShaderText(vert); 197 | 198 | m_canvas->setMode(a); 199 | m_canvas->update(); 200 | } 201 | 202 | void 203 | SGFrame::setStatusText(const QString& text) 204 | { 205 | statusBar()->showMessage(text); 206 | } 207 | 208 | bool 209 | SGFrame::isPerspective() const 210 | { 211 | return m_perspAct->isChecked(); 212 | } 213 | 214 | int 215 | SGFrame::printOglError(const char* file, int line) 216 | { 217 | if (!sgframe_instance) 218 | return 0; 219 | 220 | int retCode = 0; 221 | 222 | GLenum glErr = glGetError(); 223 | 224 | while (glErr != GL_NO_ERROR) { 225 | const QString str = QString("glError in file %1:%2: %3").arg(file).arg(line).arg(glErr); 226 | sgframe_instance->getShaderTextWindow()->log(str); 227 | retCode = 1; 228 | glErr = glGetError(); 229 | } 230 | return retCode; 231 | } 232 | 233 | bool 234 | SGFrame::loadFile(const QString& filename) 235 | { 236 | QFile loadFile(filename); 237 | 238 | if (!loadFile.open(QIODevice::ReadOnly)) { 239 | qWarning("Couldn't open save file."); 240 | return false; 241 | } 242 | 243 | QByteArray saveData = loadFile.readAll(); 244 | 245 | QJsonDocument loadDoc(QJsonDocument::fromJson(saveData)); 246 | m_glState->read(loadDoc.object()); 247 | m_oglNotebook->setup(); 248 | m_canvas->update(); 249 | 250 | return true; 251 | } 252 | 253 | bool 254 | SGFrame::saveFile(const QString& filename) const 255 | { 256 | QFile saveFile(filename); 257 | if (!saveFile.open(QIODevice::WriteOnly)) { 258 | qWarning("Couldn't open save file."); 259 | return false; 260 | } 261 | QJsonObject stateObject; 262 | m_glState->write(stateObject); 263 | QJsonDocument saveDoc(stateObject); 264 | saveFile.write(saveDoc.toJson()); 265 | 266 | return true; 267 | } 268 | 269 | void 270 | SGFrame::readSettings() 271 | { 272 | QSettings settings; 273 | restoreGeometry(settings.value("app/geometry").toByteArray()); 274 | restoreState(settings.value("app/windowState").toByteArray()); 275 | m_topSizer->restoreState(settings.value("app/topSizer").toByteArray()); 276 | m_horizSizer->restoreState(settings.value("app/horizSizer").toByteArray()); 277 | } 278 | 279 | void 280 | SGFrame::closeEvent(QCloseEvent* event) 281 | { 282 | QSettings settings; 283 | settings.setValue("app/geometry", saveGeometry()); 284 | settings.setValue("app/windowState", saveState()); 285 | settings.setValue("app/topSizer", m_topSizer->saveState()); 286 | settings.setValue("app/horizSizer", m_horizSizer->saveState()); 287 | 288 | QMainWindow::closeEvent(event); 289 | } 290 | 291 | void 292 | SGFrame::onGLModeChanged(int id) 293 | { 294 | setCanvasMode((SGCanvas::GLMode)id); 295 | } 296 | 297 | void 298 | SGFrame::modelActionTriggered(QAction* action) 299 | { 300 | if (action == m_torusAct) { 301 | m_canvas->setModel(SGCanvas::ModelTorus); 302 | } else if (action == m_sphereAct) { 303 | m_canvas->setModel(SGCanvas::ModelSphere); 304 | } else if (action == m_trefoilAct) { 305 | m_canvas->setModel(SGCanvas::ModelTrefoil); 306 | } else if (action == m_kleinAct) { 307 | m_canvas->setModel(SGCanvas::ModelKlein); 308 | } else if (action == m_conicAct) { 309 | m_canvas->setModel(SGCanvas::ModelConic); 310 | } else if (action == m_planeAct) { 311 | m_canvas->setModel(SGCanvas::ModelPlane); 312 | } 313 | 314 | m_canvas->update(); 315 | } 316 | 317 | void 318 | SGFrame::viewActionTriggered() 319 | { 320 | m_canvas->update(); 321 | } 322 | 323 | void 324 | SGFrame::switchGLModeTriggered() 325 | { 326 | if (m_canvas->getMode() == SGCanvas::GLModeChoiceFixed) { 327 | setCanvasMode(SGCanvas::GLModeChoiceShader); 328 | } else { 329 | setCanvasMode(SGCanvas::GLModeChoiceFixed); 330 | } 331 | m_canvas->update(); 332 | } 333 | 334 | void 335 | SGFrame::setFixedGLMode() 336 | { 337 | setCanvasMode(SGCanvas::GLModeChoiceFixed); 338 | m_canvas->update(); 339 | } 340 | 341 | void 342 | SGFrame::help() 343 | { 344 | QDialog help(this); 345 | help.setWindowTitle(tr("Help - ShaderGen")); 346 | auto layout = new QVBoxLayout(&help); 347 | auto txtEdit = new QTextEdit(); 348 | txtEdit->setReadOnly(true); 349 | txtEdit->setPlainText(tr("\n" 350 | "GLSL ShaderGen\n\n" 351 | "INTENDED PURPOSE:\n\n" 352 | "The purpose of ShaderGen is to show the user how to emulate fixed " 353 | "functionality\n" 354 | "by using the OpenGL Shading Language.\n\n" 355 | "ShaderGen is intended to be educational, with the focus being on " 356 | "clarity of\n" 357 | "generated code rather than efficiency.\n" 358 | " \n" 359 | " \n" 360 | "USAGE:\n\n" 361 | "The tool has three major parts:\n" 362 | "* OpenGL Window : Displays rendered output.\n" 363 | "* OpenGL State : Configure the OpenGL State using the tabs.\n" 364 | "* Shader Text Windows : Use the tabs to look through the generated " 365 | "shaders\n\n" 366 | "Operation:\n\n" 367 | "1. Using the tabs, setup the OpenGL state. You will see your " 368 | "results updated" 369 | " in the OpenGL Window as you make state changes. If you make a " 370 | "change requiring text" 371 | " entry, be sure to press the enter key to update the current state.\n" 372 | "2. Click the \"GENERATE SHADERS\" button on the Shader Windows panel " 373 | "to generate Vertex and Fragment Shaders\n" 374 | "3. Click \"COMPILE\" to compile the shaders, then check the " 375 | "\"Infolog\" text window for compilation results\n" 376 | "4. Click \"LINK\" to link the compilers, then see the \"Infolog\" " 377 | "window for results\n" 378 | "5. To switch the OpenGL Window to display the shaded model, click " 379 | "the \"Shader" 380 | " Equivalent\" mode radio button.\n" 381 | "6. Click \"BUILD\" to do steps 2 through 5 together.\n\n\n" 382 | "Note: The text boxes only accept values when enter key is pressed\n" 383 | "Note: You can edit the shaders in the text windows, and then press " 384 | "\"COMPILE\" and then \"LINK\" to" 385 | " to see the results of your edited shaders.\n" 386 | "Note: The eye coordinate distance between the model center and the " 387 | "viewpoint is 6.0. The model is" 388 | " drawn with it's center at (0.0,0.0,6.0) in eye-coordinates and " 389 | "diagonals at (-1.0, -1.0, 5.0)" 390 | " and (1.0, 1.0, 7.0).\n" 391 | " ")); 392 | 393 | layout->addWidget(txtEdit); 394 | help.resize(600, 600); 395 | help.exec(); 396 | } 397 | 398 | void 399 | SGFrame::about() 400 | { 401 | QMessageBox::about(this, 402 | "GLSL ShaderGen", 403 | QString("
" 404 | "

" 405 | "

GLSL ShaderGen

" 406 | "

Version %1

" 407 | "
") 408 | .arg(SHADERGEN_VERSION)); 409 | } 410 | 411 | bool 412 | SGFrame::open() 413 | { 414 | QString fileName = QFileDialog::getOpenFileName( 415 | this, tr("Open"), QDir::homePath(), tr("ShaderGen Files (*.json)")); 416 | if (fileName.isEmpty()) 417 | return false; 418 | 419 | return loadFile(fileName); 420 | } 421 | 422 | bool 423 | SGFrame::saveAs() 424 | { 425 | QString fileName = QFileDialog::getSaveFileName( 426 | this, tr("Save As"), QDir::homePath(), tr("ShaderGen Files (*.json)")); 427 | if (fileName.isEmpty()) 428 | return false; 429 | 430 | return saveFile(fileName); 431 | } 432 | -------------------------------------------------------------------------------- /source/SGFrame.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | 42 | #include "SGCanvas.h" 43 | #include "SGShaderGenerator.h" 44 | 45 | #include 46 | 47 | class SGOglNotebook; 48 | class SGShaderTextWindow; 49 | class SGCanvas; 50 | class SGFixedGLState; 51 | class SGTextures; 52 | class QSplitter; 53 | class QButtonGroup; 54 | 55 | #define PrintOpenGLError() SGFrame::printOglError(__FILE__, __LINE__) 56 | 57 | class SGFrame : public QMainWindow 58 | { 59 | Q_OBJECT 60 | public: 61 | SGFrame(const QString& title); 62 | ~SGFrame(); 63 | 64 | SGFixedGLState* getGLState() { return m_glState.get(); } 65 | SGTextures* getTextures() { return m_textures.get(); } 66 | 67 | SGShaderTextWindow* getShaderTextWindow() { return m_shaderText; } 68 | SGCanvas* getCanvas() { return m_canvas; } 69 | 70 | void setCanvasMode(SGCanvas::GLMode a); 71 | void setStatusText(const QString& text); 72 | bool isPerspective() const; 73 | 74 | QString getVertexShader() const { return m_shaderGen->buildVertexShader(); } 75 | QString getFragmentShader() const { return m_shaderGen->buildFragmentShader(); } 76 | 77 | /// Returns 1 if an OpenGL error occurred, 0 otherwise. 78 | static int printOglError(const char* file, int line); 79 | 80 | bool loadFile(const QString& filename); 81 | bool saveFile(const QString& filename) const; 82 | 83 | void readSettings(); 84 | 85 | protected: 86 | void closeEvent(QCloseEvent* event) override; 87 | private slots: 88 | void onGLModeChanged(int); 89 | void modelActionTriggered(QAction* action); 90 | void viewActionTriggered(); 91 | void switchGLModeTriggered(); 92 | void setFixedGLMode(); 93 | void help(); 94 | void about(); 95 | bool open(); 96 | bool saveAs(); 97 | 98 | private: 99 | void createActions(); 100 | void createMenus(); 101 | void createStatusBar(); 102 | 103 | QMenu* m_fileMenu; 104 | QMenu* m_viewMenu; 105 | QMenu* m_modelMenu; 106 | QMenu* m_helpMenu; 107 | 108 | QAction* m_openAct; 109 | QAction* m_saveAsAct; 110 | QAction* m_exitAct; 111 | QAction* m_perspAct; 112 | QAction* m_switchGLModeAct; 113 | QAction* m_torusAct; 114 | QAction* m_sphereAct; 115 | QAction* m_trefoilAct; 116 | QAction* m_kleinAct; 117 | QAction* m_conicAct; 118 | QAction* m_planeAct; 119 | QAction* m_aboutAct; 120 | QAction* m_helpAct; 121 | 122 | std::unique_ptr m_glState; 123 | std::unique_ptr m_textures; 124 | SGOglNotebook* m_oglNotebook; 125 | SGCanvas* m_canvas; 126 | QButtonGroup* m_glModeChoice; 127 | SGShaderTextWindow* m_shaderText; 128 | std::unique_ptr m_shaderGen; 129 | QSplitter* m_topSizer; 130 | QSplitter* m_horizSizer; 131 | }; 132 | -------------------------------------------------------------------------------- /source/SGOglFogNBPage.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #include "QColorButton.h" 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include "SGFixedGLState.h" 47 | #include "SGOglFogNBPage.h" 48 | 49 | SGOglFogNBPage::SGOglFogNBPage(SGFixedGLState* glState, QWidget* parent) 50 | : QWidget(parent) 51 | , m_glState(glState) 52 | { 53 | auto fogSizer = new QGridLayout(this); 54 | 55 | auto fogCoord = new QRadioButton(tr("GL_FOG_COORD"), this); 56 | auto fogFragmentDepth = new QRadioButton(tr("GL_FRAGMENT_DEPTH"), this); 57 | 58 | auto fogSourceChoiceBox = new QGroupBox(tr("Select Source"), this); 59 | auto fogSourceChoiceSizer = new QVBoxLayout(fogSourceChoiceBox); 60 | 61 | fogSourceChoiceSizer->addWidget(fogCoord); 62 | fogSourceChoiceSizer->addWidget(fogFragmentDepth); 63 | 64 | m_fogSourceChoice = new QButtonGroup(this); 65 | m_fogSourceChoice->addButton(fogCoord, 0); 66 | m_fogSourceChoice->addButton(fogFragmentDepth, 1); 67 | connect(m_fogSourceChoice, SIGNAL(buttonClicked(int)), SLOT(fogSourceChanged(int))); 68 | 69 | GLenum src = 0; 70 | switch (glState->getFog().source) { 71 | case GL_FOG_COORD: 72 | src = 0; 73 | break; 74 | case GL_FRAGMENT_DEPTH: 75 | src = 1; 76 | break; 77 | default: 78 | src = 0; 79 | break; 80 | } 81 | 82 | m_fogSourceChoice->button(src)->setChecked(true); 83 | 84 | auto fogLinear = new QRadioButton(tr("GL_LINEAR"), this); 85 | auto fogExp = new QRadioButton(tr("GL_EXP"), this); 86 | auto fogExp2 = new QRadioButton(tr("GL_EXP2"), this); 87 | 88 | auto fogModeChoiceBox = new QGroupBox(tr("Select Fog Mode"), this); 89 | auto fogModeChoiceSizer = new QVBoxLayout(fogModeChoiceBox); 90 | 91 | fogModeChoiceSizer->addWidget(fogLinear); 92 | fogModeChoiceSizer->addWidget(fogExp); 93 | fogModeChoiceSizer->addWidget(fogExp2); 94 | 95 | m_fogModeChoice = new QButtonGroup(this); 96 | m_fogModeChoice->addButton(fogLinear, 0); 97 | m_fogModeChoice->addButton(fogExp, 1); 98 | m_fogModeChoice->addButton(fogExp2, 2); 99 | connect(m_fogModeChoice, SIGNAL(buttonClicked(int)), SLOT(fogModeChanged(int))); 100 | 101 | GLenum mode = 1; 102 | switch (glState->getFog().mode) { 103 | case GL_LINEAR: 104 | mode = 0; 105 | break; 106 | case GL_EXP: 107 | mode = 1; 108 | break; 109 | case GL_EXP2: 110 | mode = 2; 111 | break; 112 | default: 113 | mode = 1; 114 | break; 115 | } 116 | 117 | m_fogModeChoice->button(mode)->setChecked(true); 118 | 119 | m_fogDensity = new QDoubleSpinBox(this); 120 | m_fogDensity->setRange(0, 100); 121 | 122 | m_fogStart = new QDoubleSpinBox(this); 123 | m_fogStart->setRange(-1000, 1000); 124 | 125 | m_fogEnd = new QDoubleSpinBox(this); 126 | m_fogEnd->setRange(-1000, 1000); 127 | 128 | connect(m_fogDensity, SIGNAL(valueChanged(double)), SLOT(fogDensityChanged(double))); 129 | connect(m_fogStart, SIGNAL(valueChanged(double)), SLOT(fogStartChanged(double))); 130 | connect(m_fogEnd, SIGNAL(valueChanged(double)), SLOT(fogEndChanged(double))); 131 | 132 | m_fogColor = new QColorButton(this); 133 | connect(m_fogColor, SIGNAL(selected(const QColor&)), SLOT(fogColorChanged(const QColor&))); 134 | 135 | auto fogDensityLbl = new QLabel(tr("GL_FOG_DENSITY"), this); 136 | auto fogStartLbl = new QLabel(tr("GL_FOG_START"), this); 137 | auto fogEndLbl = new QLabel(tr("GL_FOG_END"), this); 138 | auto fogColorLbl = new QLabel(tr("GL_FOG_COLOR"), this); 139 | 140 | m_fogCheckBox = new QCheckBox(tr("GL_FOG_ENABLE"), this); 141 | m_fogCheckBox->setChecked(glState->getFogEnable()); 142 | connect(m_fogCheckBox, SIGNAL(clicked(bool)), SLOT(onCheckbox())); 143 | 144 | fogSizer->addWidget(m_fogCheckBox, 0, 0); 145 | 146 | fogSizer->addWidget(fogSourceChoiceBox, 1, 0, 3, 1); 147 | 148 | fogSizer->addWidget(fogModeChoiceBox, 1, 1, 3, 1); 149 | 150 | fogSizer->addWidget(fogDensityLbl, 1, 2); 151 | fogSizer->addWidget(fogStartLbl, 2, 2); 152 | fogSizer->addWidget(fogEndLbl, 3, 2); 153 | 154 | fogSizer->addWidget(m_fogDensity, 1, 3); 155 | fogSizer->addWidget(m_fogStart, 2, 3); 156 | fogSizer->addWidget(m_fogEnd, 3, 3); 157 | 158 | fogSizer->addWidget(fogColorLbl, 1, 4); 159 | 160 | fogSizer->addWidget(m_fogColor, 1, 5); 161 | fogSizer->setRowStretch(4, 2); 162 | fogSizer->setColumnStretch(6, 2); 163 | 164 | setup(); 165 | } 166 | 167 | void 168 | SGOglFogNBPage::setup() 169 | { 170 | m_fogCheckBox->setChecked(m_glState->getFogEnable()); 171 | 172 | const Fog& fog = m_glState->getFog(); 173 | switch (fog.source) { 174 | case GL_FOG_COORD: 175 | m_fogSourceChoice->button(0)->setChecked(true); 176 | break; 177 | case GL_FRAGMENT_DEPTH: 178 | m_fogSourceChoice->button(1)->setChecked(true); 179 | break; 180 | } 181 | 182 | switch (fog.mode) { 183 | case GL_LINEAR: 184 | m_fogModeChoice->button(0)->setChecked(true); 185 | break; 186 | case GL_EXP: 187 | m_fogModeChoice->button(1)->setChecked(true); 188 | break; 189 | case GL_EXP2: 190 | m_fogModeChoice->button(2)->setChecked(true); 191 | break; 192 | } 193 | 194 | m_fogDensity->setValue(fog.density); 195 | m_fogStart->setValue(fog.start); 196 | m_fogEnd->setValue(fog.end); 197 | m_fogColor->setColor(fog.color); 198 | } 199 | 200 | void 201 | SGOglFogNBPage::fogColorChanged(const QColor& color) 202 | { 203 | m_glState->getFog().color = color; 204 | 205 | emit valueChanged(); 206 | } 207 | 208 | void 209 | SGOglFogNBPage::onCheckbox() 210 | { 211 | m_glState->setFogEnable(m_fogCheckBox->isChecked()); 212 | emit valueChanged(); 213 | } 214 | 215 | void 216 | SGOglFogNBPage::fogDensityChanged(double density) 217 | { 218 | m_glState->getFog().density = density; 219 | emit valueChanged(); 220 | } 221 | 222 | void 223 | SGOglFogNBPage::fogStartChanged(double start) 224 | { 225 | m_glState->getFog().start = start; 226 | emit valueChanged(); 227 | } 228 | 229 | void 230 | SGOglFogNBPage::fogEndChanged(double end) 231 | { 232 | m_glState->getFog().end = end; 233 | emit valueChanged(); 234 | } 235 | 236 | void 237 | SGOglFogNBPage::fogModeChanged(int index) 238 | { 239 | switch (index) { 240 | case 0: 241 | m_glState->getFog().mode = GL_LINEAR; 242 | break; 243 | case 1: 244 | m_glState->getFog().mode = GL_EXP; 245 | break; 246 | case 2: 247 | m_glState->getFog().mode = GL_EXP2; 248 | break; 249 | default: 250 | break; 251 | } 252 | emit valueChanged(); 253 | } 254 | 255 | void 256 | SGOglFogNBPage::fogSourceChanged(int index) 257 | { 258 | switch (index) { 259 | case 0: 260 | m_glState->getFog().source = GL_FOG_COORD; 261 | break; 262 | case 1: 263 | m_glState->getFog().source = GL_FRAGMENT_DEPTH; 264 | break; 265 | default: 266 | break; 267 | } 268 | emit valueChanged(); 269 | } 270 | -------------------------------------------------------------------------------- /source/SGOglFogNBPage.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | class SGFixedGLState; 47 | class QColorButton; 48 | 49 | class SGOglFogNBPage : public QWidget 50 | { 51 | Q_OBJECT 52 | public: 53 | SGOglFogNBPage(SGFixedGLState* m_glState, QWidget* parent); 54 | 55 | void setup(); 56 | signals: 57 | void valueChanged(); 58 | protected slots: 59 | void onCheckbox(); 60 | void fogColorChanged(const QColor& color); 61 | void fogDensityChanged(double); 62 | void fogStartChanged(double); 63 | void fogEndChanged(double); 64 | void fogModeChanged(int index); 65 | void fogSourceChanged(int index); 66 | 67 | private: 68 | SGFixedGLState* m_glState; 69 | 70 | QButtonGroup* m_fogSourceChoice; 71 | QButtonGroup* m_fogModeChoice; 72 | QColorButton* m_fogColor; 73 | QDoubleSpinBox* m_fogDensity; 74 | QDoubleSpinBox* m_fogStart; 75 | QDoubleSpinBox* m_fogEnd; 76 | QCheckBox* m_fogCheckBox; 77 | }; 78 | -------------------------------------------------------------------------------- /source/SGOglLightNBPage.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #include "QColorButton.h" 45 | #include "QVectorEdit.h" 46 | 47 | #include "SGFixedGLState.h" 48 | #include "SGOglLightNBPage.h" 49 | 50 | SGOglLightNBPage::SGOglLightNBPage(SGFixedGLState* glState, QWidget* parent) 51 | : QWidget(parent) 52 | , m_glState(glState) 53 | { 54 | auto enableDisableBox = new QGroupBox(tr("glEnable/glDisable"), this); 55 | auto lightSelectionBox = new QGroupBox(tr("Select Light"), this); 56 | auto selectedLightBox = new QGroupBox(tr("Selected Light Properties"), this); 57 | auto lightSizer = new QGridLayout(this); 58 | auto h1 = new QHBoxLayout(enableDisableBox); 59 | auto h2 = new QHBoxLayout(lightSelectionBox); 60 | auto h3 = new QGridLayout(selectedLightBox); 61 | 62 | m_lightSelectionGroup = new QButtonGroup(this); 63 | for (int i = 0; i < NUM_LIGHTS; i++) { 64 | QRadioButton* lrb = new QRadioButton(QString("L%1 ").arg(i), this); 65 | h2->addWidget(lrb); 66 | m_lightSelectionGroup->addButton(lrb, i); 67 | } 68 | m_lightSelectionGroup->button(0)->setChecked(true); 69 | connect(m_lightSelectionGroup, SIGNAL(buttonClicked(int)), SLOT(onRadio(int))); 70 | 71 | m_lightCheckGroup = new QButtonGroup(this); 72 | m_lightCheckGroup->setExclusive(false); 73 | for (int i = 0; i < NUM_LIGHTS; i++) { 74 | QCheckBox* lcb = new QCheckBox(QString("L%1").arg(i), this); 75 | h1->addWidget(lcb); 76 | m_lightCheckGroup->addButton(lcb, i); 77 | } 78 | connect(m_lightCheckGroup, SIGNAL(buttonClicked(int)), SLOT(onCheckbox(int))); 79 | 80 | m_lightingCheckBox = new QCheckBox(tr("GL_LIGHTING"), this); 81 | connect(m_lightingCheckBox, SIGNAL(clicked()), SLOT(lightingChanged())); 82 | 83 | m_twoSidedLightingCheckBox = new QCheckBox(tr("GL_LIGHT_MODEL_TWO_SIDE"), this); 84 | connect(m_twoSidedLightingCheckBox, SIGNAL(clicked()), SLOT(twoSidedLightingChanged())); 85 | 86 | m_localViewerLightingCheckBox = new QCheckBox(tr("GL_LIGHT_MODEL_LOCAL_VIEWER"), this); 87 | connect(m_localViewerLightingCheckBox, SIGNAL(clicked()), SLOT(localViewerLightingChanged())); 88 | 89 | m_normalizeCheckBox = new QCheckBox(tr("GL_NORMALIZE"), this); 90 | connect(m_normalizeCheckBox, SIGNAL(clicked()), SLOT(normalizeChanged())); 91 | 92 | m_rescaleNormalCheckBox = new QCheckBox(tr("GL_RESCALE_NORMAL"), this); 93 | connect(m_rescaleNormalCheckBox, SIGNAL(clicked()), SLOT(rescaleNormalChanged())); 94 | 95 | m_separateSpecularColorCheckBox = new QCheckBox(tr("GL_SEPARATE_SPECULAR_COLOR"), this); 96 | connect(m_separateSpecularColorCheckBox, SIGNAL(clicked()), SLOT(separateSpecularChanged())); 97 | 98 | h1->addWidget(m_lightingCheckBox); 99 | h1->addWidget(m_twoSidedLightingCheckBox); 100 | h1->addWidget(m_localViewerLightingCheckBox); 101 | h1->addWidget(m_normalizeCheckBox); 102 | h1->addWidget(m_rescaleNormalCheckBox); 103 | h1->addWidget(m_separateSpecularColorCheckBox); 104 | 105 | m_lightPosition = new QVectorEdit(this); 106 | connect(m_lightPosition, SIGNAL(valueChanged()), SLOT(lightPositionChanged())); 107 | 108 | m_spotDirection = new QVectorEdit(this); 109 | m_spotDirection->setNumFields(3); 110 | connect(m_spotDirection, SIGNAL(valueChanged()), SLOT(spotDirectionChanged())); 111 | 112 | m_spotExponent = new QDoubleSpinBox(this); 113 | m_spotExponent->setRange(-1000, 1000); 114 | connect(m_spotExponent, SIGNAL(valueChanged(double)), SLOT(spotExponentChanged())); 115 | 116 | m_spotCutoff = new QDoubleSpinBox(this); 117 | m_spotCutoff->setRange(-1000, 1000); 118 | connect(m_spotCutoff, SIGNAL(valueChanged(double)), SLOT(spotCutoffChanged())); 119 | 120 | m_constantAttenuation = new QDoubleSpinBox(this); 121 | m_constantAttenuation->setRange(-1000, 1000); 122 | connect( 123 | m_constantAttenuation, SIGNAL(valueChanged(double)), SLOT(constantAttenuationChanged())); 124 | 125 | m_linearAttenuation = new QDoubleSpinBox(this); 126 | m_linearAttenuation->setRange(-1000, 1000); 127 | connect(m_linearAttenuation, SIGNAL(valueChanged(double)), SLOT(linearAttenuationChanged())); 128 | 129 | m_quadraticAttenuation = new QDoubleSpinBox(this); 130 | m_quadraticAttenuation->setRange(-1000, 1000); 131 | connect( 132 | m_quadraticAttenuation, SIGNAL(valueChanged(double)), SLOT(quadraticAttenuationChanged())); 133 | 134 | m_ambientLight = new QColorButton(this); 135 | connect(m_ambientLight, SIGNAL(clicked()), SLOT(ambientLightChanged())); 136 | 137 | m_specularLight = new QColorButton(this); 138 | connect(m_specularLight, SIGNAL(clicked()), SLOT(specularLightChanged())); 139 | 140 | m_diffuseLight = new QColorButton(this); 141 | connect(m_diffuseLight, SIGNAL(clicked()), SLOT(diffuseLightChanged())); 142 | 143 | auto positionLbl = new QLabel(tr("GL_POSITION"), this); 144 | 145 | auto ambientLbl = new QLabel(tr("GL_AMBIENT"), this); 146 | auto specularLbl = new QLabel(tr("GL_SPECULAR"), this); 147 | auto diffuseLbl = new QLabel(tr("GL_DIFFUSE"), this); 148 | 149 | auto spotDirectionLbl = new QLabel(tr("GL_SPOT_DIRECTION"), this); 150 | auto spotExponentLbl = new QLabel(tr("GL_SPOT_EXPONENT"), this); 151 | auto spotCutoffLbl = new QLabel(tr("GL_SPOT_CUTOFF"), this); 152 | 153 | auto constantAttenLbl = new QLabel(tr("GL_CONSTANT_ATTENUATION"), this); 154 | auto linearAttenLbl = new QLabel(tr("GL_LINEAR_ATTENUATION"), this); 155 | auto quadraticAttenLbl = new QLabel(tr("GL_QUADRATIC_ATTENUATION"), this); 156 | 157 | h3->addWidget(positionLbl, 0, 0); 158 | 159 | h3->addWidget(m_lightPosition, 0, 1); 160 | 161 | h3->addWidget(ambientLbl, 0, 2); 162 | h3->addWidget(specularLbl, 1, 2); 163 | h3->addWidget(diffuseLbl, 2, 2); 164 | 165 | h3->addWidget(m_ambientLight, 0, 3); 166 | h3->addWidget(m_specularLight, 1, 3); 167 | h3->addWidget(m_diffuseLight, 2, 3); 168 | 169 | h3->addWidget(spotDirectionLbl, 0, 4); 170 | h3->addWidget(spotExponentLbl, 1, 4); 171 | h3->addWidget(spotCutoffLbl, 2, 4); 172 | 173 | h3->addWidget(m_spotDirection, 0, 5); 174 | h3->addWidget(m_spotExponent, 1, 5); 175 | h3->addWidget(m_spotCutoff, 2, 5); 176 | 177 | h3->addWidget(constantAttenLbl, 0, 6); 178 | h3->addWidget(linearAttenLbl, 1, 6); 179 | h3->addWidget(quadraticAttenLbl, 2, 6); 180 | 181 | h3->addWidget(m_constantAttenuation, 0, 7); 182 | h3->addWidget(m_linearAttenuation, 1, 7); 183 | h3->addWidget(m_quadraticAttenuation, 2, 7); 184 | 185 | lightSizer->addWidget(enableDisableBox, 0, 0, 1, 2); 186 | lightSizer->addWidget(lightSelectionBox, 1, 0, 1, 1); 187 | lightSizer->addWidget(selectedLightBox, 2, 0, 1, 3); 188 | lightSizer->setRowStretch(3, 2); 189 | lightSizer->setColumnStretch(4, 2); 190 | 191 | setup(); 192 | } 193 | 194 | void 195 | SGOglLightNBPage::setup() 196 | { 197 | for (int i = 0; i < NUM_LIGHTS; i++) { 198 | m_lightCheckGroup->button(i)->setChecked(m_glState->getLight(i).enabled); 199 | } 200 | m_lightingCheckBox->setChecked(m_glState->getLightingEnable()); 201 | m_twoSidedLightingCheckBox->setChecked(m_glState->getTwoSidedLightingEnable()); 202 | m_localViewerLightingCheckBox->setChecked(m_glState->getLocalViewerLightingEnable()); 203 | m_normalizeCheckBox->setChecked(m_glState->getNormalizeEnable()); 204 | m_rescaleNormalCheckBox->setChecked(m_glState->getRescaleNormalEnable()); 205 | m_separateSpecularColorCheckBox->setChecked(m_glState->getSeparateSpecularColorEnable()); 206 | 207 | const Light& light = m_glState->getLight(m_lightSelectionGroup->checkedId()); 208 | 209 | m_lightPosition->setValue(light.position); 210 | m_spotDirection->setValue(light.spotDirection); 211 | m_spotExponent->setValue(light.spotExponent); 212 | m_spotCutoff->setValue(light.spotCutoff); 213 | m_constantAttenuation->setValue(light.constantAttenuation); 214 | m_linearAttenuation->setValue(light.linearAttenuation); 215 | m_quadraticAttenuation->setValue(light.quadraticAttenuation); 216 | m_ambientLight->setColor(light.ambientColor); 217 | m_specularLight->setColor(light.specularColor); 218 | m_diffuseLight->setColor(light.diffuseColor); 219 | } 220 | 221 | void 222 | SGOglLightNBPage::lightingChanged() 223 | { 224 | m_glState->setLightingEnable(m_lightingCheckBox->isChecked()); 225 | emit valueChanged(); 226 | } 227 | 228 | void 229 | SGOglLightNBPage::twoSidedLightingChanged() 230 | { 231 | m_glState->setTwoSidedLightingEnable(m_twoSidedLightingCheckBox->isChecked()); 232 | emit valueChanged(); 233 | } 234 | 235 | void 236 | SGOglLightNBPage::localViewerLightingChanged() 237 | { 238 | m_glState->setLocalViewerLightingEnable(m_localViewerLightingCheckBox->isChecked()); 239 | emit valueChanged(); 240 | } 241 | 242 | void 243 | SGOglLightNBPage::normalizeChanged() 244 | { 245 | m_glState->setNormalizeEnable(m_normalizeCheckBox->isChecked()); 246 | emit valueChanged(); 247 | } 248 | 249 | void 250 | SGOglLightNBPage::rescaleNormalChanged() 251 | { 252 | m_glState->setRescaleNormalEnable(m_rescaleNormalCheckBox->isChecked()); 253 | emit valueChanged(); 254 | } 255 | 256 | void 257 | SGOglLightNBPage::separateSpecularChanged() 258 | { 259 | m_glState->setSeparateSpecularColorEnable(m_separateSpecularColorCheckBox->isChecked()); 260 | emit valueChanged(); 261 | } 262 | 263 | void 264 | SGOglLightNBPage::ambientLightChanged() 265 | { 266 | int lightSelected = m_lightSelectionGroup->checkedId(); 267 | m_glState->getLight(lightSelected).ambientColor = m_ambientLight->color(); 268 | 269 | emit valueChanged(); 270 | } 271 | 272 | void 273 | SGOglLightNBPage::specularLightChanged() 274 | { 275 | int lightSelected = m_lightSelectionGroup->checkedId(); 276 | m_glState->getLight(lightSelected).specularColor = m_specularLight->color(); 277 | 278 | emit valueChanged(); 279 | } 280 | 281 | void 282 | SGOglLightNBPage::diffuseLightChanged() 283 | { 284 | int lightSelected = m_lightSelectionGroup->checkedId(); 285 | m_glState->getLight(lightSelected).diffuseColor = m_diffuseLight->color(); 286 | 287 | emit valueChanged(); 288 | } 289 | 290 | void 291 | SGOglLightNBPage::onCheckbox(int index) 292 | { 293 | const QAbstractButton* btn = m_lightCheckGroup->button(index); 294 | m_glState->getLight(index).enabled = btn->isChecked(); 295 | 296 | emit valueChanged(); 297 | } 298 | 299 | void 300 | SGOglLightNBPage::spotExponentChanged() 301 | { 302 | int lightSelected = m_lightSelectionGroup->checkedId(); 303 | m_glState->getLight(lightSelected).spotExponent = m_spotExponent->value(); 304 | emit valueChanged(); 305 | } 306 | 307 | void 308 | SGOglLightNBPage::spotCutoffChanged() 309 | { 310 | int lightSelected = m_lightSelectionGroup->checkedId(); 311 | m_glState->getLight(lightSelected).spotCutoff = m_spotCutoff->value(); 312 | emit valueChanged(); 313 | } 314 | 315 | void 316 | SGOglLightNBPage::constantAttenuationChanged() 317 | { 318 | int lightSelected = m_lightSelectionGroup->checkedId(); 319 | m_glState->getLight(lightSelected).constantAttenuation = m_constantAttenuation->value(); 320 | emit valueChanged(); 321 | } 322 | 323 | void 324 | SGOglLightNBPage::quadraticAttenuationChanged() 325 | { 326 | int lightSelected = m_lightSelectionGroup->checkedId(); 327 | m_glState->getLight(lightSelected).quadraticAttenuation = m_quadraticAttenuation->value(); 328 | emit valueChanged(); 329 | } 330 | 331 | void 332 | SGOglLightNBPage::linearAttenuationChanged() 333 | { 334 | int lightSelected = m_lightSelectionGroup->checkedId(); 335 | m_glState->getLight(lightSelected).linearAttenuation = m_linearAttenuation->value(); 336 | emit valueChanged(); 337 | } 338 | 339 | void 340 | SGOglLightNBPage::lightPositionChanged() 341 | { 342 | QVector4D tempLightPosVector = m_lightPosition->getValue(); 343 | if (tempLightPosVector.w() != 1 && tempLightPosVector.w() != 0.0) { 344 | QMessageBox::warning(this, tr(""), tr("The w component of GL_POSITION must be 0.0 or 1.0")); 345 | } 346 | 347 | int lightSelected = m_lightSelectionGroup->checkedId(); 348 | m_glState->getLight(lightSelected).position = tempLightPosVector; 349 | emit valueChanged(); 350 | } 351 | 352 | void 353 | SGOglLightNBPage::spotDirectionChanged() 354 | { 355 | QVector4D tempLightSpotDirectionVector = m_spotDirection->getValue(); 356 | int lightSelected = m_lightSelectionGroup->checkedId(); 357 | m_glState->getLight(lightSelected).spotDirection = QVector3D(tempLightSpotDirectionVector.x(), 358 | tempLightSpotDirectionVector.y(), 359 | tempLightSpotDirectionVector.z()); 360 | emit valueChanged(); 361 | } 362 | 363 | void 364 | SGOglLightNBPage::onRadio(int index) 365 | { 366 | const Light& light = m_glState->getLight(index); 367 | 368 | m_ambientLight->setColor(light.ambientColor); 369 | m_diffuseLight->setColor(light.diffuseColor); 370 | m_specularLight->setColor(light.specularColor); 371 | m_spotDirection->setValue(light.spotDirection); 372 | m_spotExponent->setValue(light.spotExponent); 373 | m_spotCutoff->setValue(light.spotCutoff); 374 | 375 | m_constantAttenuation->setValue(light.constantAttenuation); 376 | m_quadraticAttenuation->setValue(light.quadraticAttenuation); 377 | m_linearAttenuation->setValue(light.linearAttenuation); 378 | 379 | m_lightPosition->setValue(light.position); 380 | 381 | emit valueChanged(); 382 | } 383 | -------------------------------------------------------------------------------- /source/SGOglLightNBPage.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | class SGFixedGLState; 47 | class QColorButton; 48 | class QVectorEdit; 49 | 50 | class SGOglLightNBPage : public QWidget 51 | { 52 | Q_OBJECT 53 | public: 54 | SGOglLightNBPage(SGFixedGLState* glState, QWidget* parent); 55 | 56 | void setup(); 57 | signals: 58 | void valueChanged(); 59 | private slots: 60 | void onCheckbox(int index); 61 | void onRadio(int index); 62 | void lightingChanged(); 63 | void twoSidedLightingChanged(); 64 | void localViewerLightingChanged(); 65 | void normalizeChanged(); 66 | void rescaleNormalChanged(); 67 | void separateSpecularChanged(); 68 | void lightPositionChanged(); 69 | void spotDirectionChanged(); 70 | void spotExponentChanged(); 71 | void spotCutoffChanged(); 72 | void constantAttenuationChanged(); 73 | void quadraticAttenuationChanged(); 74 | void linearAttenuationChanged(); 75 | void ambientLightChanged(); 76 | void specularLightChanged(); 77 | void diffuseLightChanged(); 78 | 79 | private: 80 | SGFixedGLState* m_glState; 81 | 82 | QButtonGroup *m_lightSelectionGroup, *m_lightCheckGroup; 83 | 84 | QCheckBox *m_lightingCheckBox, *m_twoSidedLightingCheckBox, *m_localViewerLightingCheckBox, 85 | *m_normalizeCheckBox, *m_rescaleNormalCheckBox, *m_separateSpecularColorCheckBox; 86 | 87 | QVectorEdit* m_lightPosition; 88 | 89 | QVectorEdit* m_spotDirection; 90 | QDoubleSpinBox* m_spotExponent; 91 | QDoubleSpinBox* m_spotCutoff; 92 | 93 | QDoubleSpinBox* m_constantAttenuation; 94 | QDoubleSpinBox* m_quadraticAttenuation; 95 | QDoubleSpinBox* m_linearAttenuation; 96 | 97 | QColorButton* m_ambientLight; 98 | QColorButton* m_specularLight; 99 | QColorButton* m_diffuseLight; 100 | }; 101 | -------------------------------------------------------------------------------- /source/SGOglMaterialNBPage.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | #include "QColorButton.h" 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include "SGFixedGLState.h" 44 | #include "SGOglMaterialNBPage.h" 45 | 46 | SGOglMaterialNBPage::SGOglMaterialNBPage(SGFixedGLState* glState, QWidget* parent) 47 | : QWidget(parent) 48 | , m_glState(glState) 49 | { 50 | auto materialSizer = new QGridLayout(this); 51 | 52 | m_shininessMaterial = new QDoubleSpinBox(this); 53 | m_shininessMaterial->setRange(0, 1000); 54 | connect(m_shininessMaterial, SIGNAL(valueChanged(double)), SLOT(shininessChanged())); 55 | 56 | m_ambientMaterial = new QColorButton(this); 57 | connect(m_ambientMaterial, SIGNAL(selected(QColor)), SLOT(ambientChanged())); 58 | 59 | m_diffuseMaterial = new QColorButton(this); 60 | connect(m_diffuseMaterial, SIGNAL(selected(QColor)), SLOT(diffuseChanged())); 61 | 62 | m_specularMaterial = new QColorButton(this); 63 | connect(m_specularMaterial, SIGNAL(selected(QColor)), SLOT(specularChanged())); 64 | 65 | m_emissionMaterial = new QColorButton(this); 66 | connect(m_emissionMaterial, SIGNAL(selected(QColor)), SLOT(emissionChanged())); 67 | 68 | auto ambientMatLbl = new QLabel(tr("GL_AMBIENT"), this); 69 | auto specularMatLbl = new QLabel(tr("GL_SPECULAR"), this); 70 | auto diffuseMatLbl = new QLabel(tr("GL_DIFFUSE"), this); 71 | auto shininessLbl = new QLabel(tr("GL_SHININESS"), this); 72 | auto emissionLbl = new QLabel(tr("GL_EMISSION"), this); 73 | 74 | materialSizer->addWidget(ambientMatLbl, 0, 0); 75 | materialSizer->addWidget(diffuseMatLbl, 1, 0); 76 | materialSizer->addWidget(specularMatLbl, 2, 0); 77 | 78 | materialSizer->addWidget(m_ambientMaterial, 0, 1); 79 | materialSizer->addWidget(m_diffuseMaterial, 1, 1); 80 | materialSizer->addWidget(m_specularMaterial, 2, 1); 81 | 82 | materialSizer->addWidget(shininessLbl, 0, 2); 83 | materialSizer->addWidget(emissionLbl, 1, 2); 84 | 85 | materialSizer->addWidget(m_shininessMaterial, 0, 3); 86 | materialSizer->addWidget(m_emissionMaterial, 1, 3); 87 | 88 | materialSizer->setColumnStretch(4, 2); 89 | materialSizer->setRowStretch(3, 2); 90 | 91 | setup(); 92 | } 93 | 94 | void 95 | SGOglMaterialNBPage::setup() 96 | { 97 | const Material& mat = m_glState->getMaterial(); 98 | m_shininessMaterial->setValue(mat.shininess); 99 | m_ambientMaterial->setColor(mat.ambientColor); 100 | m_diffuseMaterial->setColor(mat.diffuseColor); 101 | m_specularMaterial->setColor(mat.specularColor); 102 | m_emissionMaterial->setColor(mat.emissionColor); 103 | } 104 | 105 | void 106 | SGOglMaterialNBPage::ambientChanged() 107 | { 108 | Material& mat = m_glState->getMaterial(); 109 | 110 | mat.ambientColor = m_ambientMaterial->color(); 111 | 112 | emit valueChanged(); 113 | } 114 | 115 | void 116 | SGOglMaterialNBPage::diffuseChanged() 117 | { 118 | Material& mat = m_glState->getMaterial(); 119 | 120 | mat.diffuseColor = m_diffuseMaterial->color(); 121 | 122 | emit valueChanged(); 123 | } 124 | 125 | void 126 | SGOglMaterialNBPage::specularChanged() 127 | { 128 | Material& mat = m_glState->getMaterial(); 129 | 130 | mat.specularColor = m_specularMaterial->color(); 131 | 132 | emit valueChanged(); 133 | } 134 | 135 | void 136 | SGOglMaterialNBPage::emissionChanged() 137 | { 138 | Material& mat = m_glState->getMaterial(); 139 | 140 | mat.emissionColor = m_emissionMaterial->color(); 141 | 142 | emit valueChanged(); 143 | } 144 | 145 | void 146 | SGOglMaterialNBPage::shininessChanged() 147 | { 148 | m_glState->getMaterial().shininess = m_shininessMaterial->value(); 149 | 150 | emit valueChanged(); 151 | } 152 | -------------------------------------------------------------------------------- /source/SGOglMaterialNBPage.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | 43 | class SGFixedGLState; 44 | class QColorButton; 45 | 46 | class SGOglMaterialNBPage : public QWidget 47 | { 48 | Q_OBJECT 49 | public: 50 | SGOglMaterialNBPage(SGFixedGLState* m_glState, QWidget* parent); 51 | 52 | void setup(); 53 | signals: 54 | void valueChanged(); 55 | private slots: 56 | void ambientChanged(); 57 | void diffuseChanged(); 58 | void specularChanged(); 59 | void emissionChanged(); 60 | void shininessChanged(); 61 | 62 | private: 63 | SGFixedGLState* m_glState; 64 | 65 | QDoubleSpinBox* m_shininessMaterial; 66 | 67 | QColorButton* m_ambientMaterial; 68 | QColorButton* m_diffuseMaterial; 69 | QColorButton* m_specularMaterial; 70 | QColorButton* m_emissionMaterial; 71 | }; 72 | -------------------------------------------------------------------------------- /source/SGOglNotebook.cpp: -------------------------------------------------------------------------------- 1 | #include "SGOglNotebook.h" 2 | #include "SGFixedGLState.h" 3 | #include "SGFrame.h" 4 | #include "SGOglFogNBPage.h" 5 | #include "SGOglLightNBPage.h" 6 | #include "SGOglMaterialNBPage.h" 7 | #include "SGOglTextureCoordNBPage.h" 8 | #include "SGOglTextureEnvNBPage.h" 9 | #include "SGTextures.h" 10 | 11 | SGOglNotebook::SGOglNotebook(SGFixedGLState* glState, QWidget* parent) 12 | : QTabWidget(parent) 13 | { 14 | m_lightPage = new SGOglLightNBPage(glState, this); 15 | m_materialPage = new SGOglMaterialNBPage(glState, this); 16 | m_fogPage = new SGOglFogNBPage(glState, this); 17 | m_textureCoordPage = new SGOglTextureCoordNBPage(glState, this); 18 | m_textureEnvPage = new SGOglTextureEnvNBPage(glState, this); 19 | 20 | connect(m_lightPage, SIGNAL(valueChanged()), SLOT(onValueChange())); 21 | connect(m_materialPage, SIGNAL(valueChanged()), SLOT(onValueChange())); 22 | connect(m_fogPage, SIGNAL(valueChanged()), SLOT(onValueChange())); 23 | connect(m_textureCoordPage, SIGNAL(valueChanged()), SLOT(onValueChange())); 24 | connect(m_textureEnvPage, SIGNAL(valueChanged()), SLOT(onValueChange())); 25 | 26 | addTab(m_lightPage, tr("LIGHT")); 27 | addTab(m_materialPage, tr("MATERIAL")); 28 | addTab(m_fogPage, tr("FOG")); 29 | addTab(m_textureCoordPage, tr("TEXTURE COORDINATE SET")); 30 | addTab(m_textureEnvPage, tr("TEXTURE ENVIRONMENT SET")); 31 | } 32 | 33 | void 34 | SGOglNotebook::setup() 35 | { 36 | m_lightPage->setup(); 37 | m_materialPage->setup(); 38 | m_fogPage->setup(); 39 | m_textureCoordPage->setup(); 40 | m_textureEnvPage->setup(); 41 | } 42 | 43 | void 44 | SGOglNotebook::onValueChange() 45 | { 46 | emit valueChanged(); 47 | } 48 | -------------------------------------------------------------------------------- /source/SGOglNotebook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class SGOglLightNBPage; 6 | class SGOglMaterialNBPage; 7 | class SGOglFogNBPage; 8 | class SGFixedGLState; 9 | class SGOglTextureCoordNBPage; 10 | class SGOglTextureEnvNBPage; 11 | 12 | class SGOglNotebook : public QTabWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | SGOglNotebook(SGFixedGLState* glState, QWidget* parent = 0); 17 | ~SGOglNotebook() = default; 18 | 19 | void setup(); 20 | signals: 21 | void valueChanged(); 22 | private slots: 23 | void onValueChange(); 24 | 25 | private: 26 | SGOglLightNBPage* m_lightPage; 27 | SGOglMaterialNBPage* m_materialPage; 28 | SGOglFogNBPage* m_fogPage; 29 | SGOglTextureCoordNBPage* m_textureCoordPage; 30 | SGOglTextureEnvNBPage* m_textureEnvPage; 31 | }; 32 | -------------------------------------------------------------------------------- /source/SGOglTextureCoordNBPage.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #include "QVectorEdit.h" 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include "SGFixedGLState.h" 47 | #include "SGOglTextureCoordNBPage.h" 48 | 49 | SGOglTextureCoordNBPage::SGOglTextureCoordNBPage(SGFixedGLState* glState, QWidget* parent) 50 | : QWidget(parent) 51 | , m_glState(glState) 52 | { 53 | QGroupBox* texPropertyBox = new QGroupBox(tr("Selected Texture Properties"), this); 54 | 55 | auto textureSizer = new QGridLayout(this); 56 | auto selectedTexPropertiesSizer = new QGridLayout(texPropertyBox); 57 | 58 | auto eyePlaneCoeffBox = new QGroupBox(tr("Eye Plane Coefficients"), this); 59 | auto eyePlaneCoeffBoxSizer = new QHBoxLayout(eyePlaneCoeffBox); 60 | 61 | auto eyePlaneLabelSizer = new QVBoxLayout(); 62 | auto eyePlaneTextSizer = new QVBoxLayout(); 63 | 64 | auto eyePlaneCoeffLabelS = new QLabel(tr("GL_S"), this); 65 | auto eyePlaneCoeffLabelT = new QLabel(tr("GL_T"), this); 66 | 67 | m_eyePlaneCoeffTextS = new QVectorEdit(this); 68 | connect(m_eyePlaneCoeffTextS, SIGNAL(valueChanged()), SLOT(onTextEnterEyeCoeffS())); 69 | 70 | m_eyePlaneCoeffTextT = new QVectorEdit(this); 71 | connect(m_eyePlaneCoeffTextT, SIGNAL(valueChanged()), SLOT(onTextEnterEyeCoeffT())); 72 | 73 | eyePlaneLabelSizer->addWidget(eyePlaneCoeffLabelS); 74 | eyePlaneLabelSizer->addWidget(eyePlaneCoeffLabelT); 75 | 76 | eyePlaneTextSizer->addWidget(m_eyePlaneCoeffTextS); 77 | eyePlaneTextSizer->addWidget(m_eyePlaneCoeffTextT); 78 | 79 | eyePlaneCoeffBoxSizer->addLayout(eyePlaneLabelSizer); 80 | eyePlaneCoeffBoxSizer->addLayout(eyePlaneTextSizer); 81 | 82 | auto objectPlaneCoeffBox = new QGroupBox(tr("Object Plane Coefficients"), this); 83 | auto objectPlaneCoeffBoxSizer = new QHBoxLayout(objectPlaneCoeffBox); 84 | 85 | auto objectPlaneLabelSizer = new QVBoxLayout(); 86 | auto objectPlaneTextSizer = new QVBoxLayout(); 87 | 88 | auto objectPlaneCoeffLabelS = new QLabel(tr("GL_S"), this); 89 | auto objectPlaneCoeffLabelT = new QLabel(tr("GL_T"), this); 90 | 91 | m_objectPlaneCoeffTextS = new QVectorEdit(this); 92 | connect(m_objectPlaneCoeffTextS, SIGNAL(valueChanged()), SLOT(onTextEnterObjCoeffS())); 93 | 94 | m_objectPlaneCoeffTextT = new QVectorEdit(this); 95 | connect(m_objectPlaneCoeffTextT, SIGNAL(valueChanged()), SLOT(onTextEnterObjCoeffT())); 96 | 97 | objectPlaneLabelSizer->addWidget(objectPlaneCoeffLabelS); 98 | objectPlaneLabelSizer->addWidget(objectPlaneCoeffLabelT); 99 | 100 | objectPlaneTextSizer->addWidget(m_objectPlaneCoeffTextS); 101 | objectPlaneTextSizer->addWidget(m_objectPlaneCoeffTextT); 102 | 103 | objectPlaneCoeffBoxSizer->addLayout(objectPlaneLabelSizer); 104 | objectPlaneCoeffBoxSizer->addLayout(objectPlaneTextSizer); 105 | 106 | auto texCoordUnitBox = new QGroupBox(tr("Selected Texture Unit"), this); 107 | auto texCoordUnitSizer = new QHBoxLayout(texCoordUnitBox); 108 | 109 | auto tex0TexSelRadioButton = new QRadioButton(tr("T0"), this); 110 | auto tex1TexSelRadioButton = new QRadioButton(tr("T1"), this); 111 | auto tex2TexSelRadioButton = new QRadioButton(tr("T2"), this); 112 | auto tex3TexSelRadioButton = new QRadioButton(tr("T3"), this); 113 | auto tex4TexSelRadioButton = new QRadioButton(tr("T4"), this); 114 | 115 | texCoordUnitSizer->addWidget(tex0TexSelRadioButton); 116 | texCoordUnitSizer->addWidget(tex1TexSelRadioButton); 117 | texCoordUnitSizer->addWidget(tex2TexSelRadioButton); 118 | texCoordUnitSizer->addWidget(tex3TexSelRadioButton); 119 | texCoordUnitSizer->addWidget(tex4TexSelRadioButton); 120 | 121 | m_texCoordUnitGroup = new QButtonGroup(this); 122 | m_texCoordUnitGroup->addButton(tex0TexSelRadioButton, 0); 123 | m_texCoordUnitGroup->addButton(tex1TexSelRadioButton, 1); 124 | m_texCoordUnitGroup->addButton(tex2TexSelRadioButton, 2); 125 | m_texCoordUnitGroup->addButton(tex3TexSelRadioButton, 3); 126 | m_texCoordUnitGroup->addButton(tex4TexSelRadioButton, 4); 127 | m_texCoordUnitGroup->button(0)->setChecked(true); 128 | connect(m_texCoordUnitGroup, SIGNAL(buttonClicked(int)), SLOT(onRadioTextureCoordUnit(int))); 129 | 130 | m_tex0TexGenEnableCheckBox = new QCheckBox(tr("T0"), this); 131 | m_tex1TexGenEnableCheckBox = new QCheckBox(tr("T1"), this); 132 | m_tex2TexGenEnableCheckBox = new QCheckBox(tr("T2"), this); 133 | m_tex3TexGenEnableCheckBox = new QCheckBox(tr("T3"), this); 134 | m_tex4TexGenEnableCheckBox = new QCheckBox(tr("T4"), this); 135 | 136 | auto texGenEnableDisableBox = new QGroupBox(tr("glEnable/glDisable TexGen"), this); 137 | auto texGenEnableDisableSizer = new QHBoxLayout(texGenEnableDisableBox); 138 | 139 | texGenEnableDisableSizer->addWidget(m_tex0TexGenEnableCheckBox); 140 | texGenEnableDisableSizer->addWidget(m_tex1TexGenEnableCheckBox); 141 | texGenEnableDisableSizer->addWidget(m_tex2TexGenEnableCheckBox); 142 | texGenEnableDisableSizer->addWidget(m_tex3TexGenEnableCheckBox); 143 | texGenEnableDisableSizer->addWidget(m_tex4TexGenEnableCheckBox); 144 | 145 | m_texCoordSelGroup = new QButtonGroup(this); 146 | m_texCoordSelGroup->setExclusive(false); 147 | m_texCoordSelGroup->addButton(m_tex0TexGenEnableCheckBox, 0); 148 | m_texCoordSelGroup->addButton(m_tex1TexGenEnableCheckBox, 1); 149 | m_texCoordSelGroup->addButton(m_tex2TexGenEnableCheckBox, 2); 150 | m_texCoordSelGroup->addButton(m_tex3TexGenEnableCheckBox, 3); 151 | m_texCoordSelGroup->addButton(m_tex4TexGenEnableCheckBox, 4); 152 | connect(m_texCoordSelGroup, SIGNAL(buttonClicked(int)), SLOT(onCheckbox(int))); 153 | 154 | auto coordGenBox = 155 | new QGroupBox(tr("Texture Coordinate Generation Method (Vertex Shader)"), this); 156 | auto coordGenSizer = new QVBoxLayout(coordGenBox); 157 | 158 | auto olinearCoordGenRadioButton = new QRadioButton(tr("GL_OBJECT_LINEAR"), this); 159 | auto elinearCoordGenRadioButton = new QRadioButton(tr("GL_EYE_LINEAR"), this); 160 | auto spheremCoordGenRadioButton = new QRadioButton(tr("GL_SPHERE_MAP"), this); 161 | auto reflecmCoordGenRadioButton = new QRadioButton(tr("GL_REFLECTION_MAP"), this); 162 | auto normalmCoordGenRadioButton = new QRadioButton(tr("GL_NORMAL_MAP"), this); 163 | 164 | coordGenSizer->addWidget(olinearCoordGenRadioButton); 165 | coordGenSizer->addWidget(elinearCoordGenRadioButton); 166 | coordGenSizer->addWidget(spheremCoordGenRadioButton); 167 | coordGenSizer->addWidget(reflecmCoordGenRadioButton); 168 | coordGenSizer->addWidget(normalmCoordGenRadioButton); 169 | 170 | m_coordGenGroup = new QButtonGroup(this); 171 | m_coordGenGroup->addButton(olinearCoordGenRadioButton, 0); 172 | m_coordGenGroup->addButton(elinearCoordGenRadioButton, 1); 173 | m_coordGenGroup->addButton(spheremCoordGenRadioButton, 2); 174 | m_coordGenGroup->addButton(reflecmCoordGenRadioButton, 3); 175 | m_coordGenGroup->addButton(normalmCoordGenRadioButton, 4); 176 | m_coordGenGroup->button(0)->setChecked(true); 177 | connect(m_coordGenGroup, SIGNAL(buttonClicked(int)), SLOT(onRadioTexCoordGen(int))); 178 | 179 | selectedTexPropertiesSizer->addWidget(coordGenBox, 0, 0, 2, 1); 180 | selectedTexPropertiesSizer->addWidget(eyePlaneCoeffBox, 0, 1); 181 | selectedTexPropertiesSizer->addWidget(objectPlaneCoeffBox, 0, 2); 182 | 183 | textureSizer->addWidget(texGenEnableDisableBox, 0, 0); 184 | textureSizer->addWidget(texCoordUnitBox, 1, 0); 185 | textureSizer->addWidget(texPropertyBox, 2, 0, 1, 2); 186 | textureSizer->setRowStretch(2, 2); 187 | textureSizer->setColumnStretch(2, 2); 188 | 189 | setup(); 190 | } 191 | 192 | void 193 | SGOglTextureCoordNBPage::setup() 194 | { 195 | m_eyePlaneCoeffTextS->setValue(m_glState->getTexture(0).eyePlaneCoeffS); 196 | m_eyePlaneCoeffTextT->setValue(m_glState->getTexture(0).eyePlaneCoeffT); 197 | m_objectPlaneCoeffTextS->setValue(m_glState->getTexture(0).objectPlaneCoeffS); 198 | m_objectPlaneCoeffTextT->setValue(m_glState->getTexture(0).objectPlaneCoeffT); 199 | 200 | m_tex0TexGenEnableCheckBox->setChecked(m_glState->getTexture(0).texGen); 201 | m_tex1TexGenEnableCheckBox->setChecked(m_glState->getTexture(1).texGen); 202 | m_tex2TexGenEnableCheckBox->setChecked(m_glState->getTexture(2).texGen); 203 | m_tex3TexGenEnableCheckBox->setChecked(m_glState->getTexture(3).texGen); 204 | m_tex4TexGenEnableCheckBox->setChecked(m_glState->getTexture(4).texGen); 205 | 206 | const Texture& texture = m_glState->getTexture(m_texCoordUnitGroup->checkedId()); 207 | 208 | switch (texture.coordinateGeneration) { 209 | case GL_OBJECT_LINEAR: 210 | m_coordGenGroup->button(0)->setChecked(true); 211 | break; 212 | case GL_EYE_LINEAR: 213 | m_coordGenGroup->button(1)->setChecked(true); 214 | break; 215 | case GL_SPHERE_MAP: 216 | m_coordGenGroup->button(2)->setChecked(true); 217 | break; 218 | case GL_REFLECTION_MAP: 219 | m_coordGenGroup->button(3)->setChecked(true); 220 | break; 221 | case GL_NORMAL_MAP: 222 | m_coordGenGroup->button(4)->setChecked(true); 223 | break; 224 | default: 225 | break; 226 | } 227 | 228 | m_eyePlaneCoeffTextS->setValue(texture.eyePlaneCoeffS); 229 | m_eyePlaneCoeffTextT->setValue(texture.eyePlaneCoeffT); 230 | m_objectPlaneCoeffTextS->setValue(texture.objectPlaneCoeffS); 231 | m_objectPlaneCoeffTextT->setValue(texture.objectPlaneCoeffT); 232 | } 233 | 234 | void 235 | SGOglTextureCoordNBPage::onRadioTextureCoordUnit(int) 236 | { 237 | updateWidgets(); 238 | emit valueChanged(); 239 | } 240 | 241 | void 242 | SGOglTextureCoordNBPage::onRadioTexCoordGen(int index) 243 | { 244 | const int workingTextureCoords = m_texCoordUnitGroup->checkedId(); 245 | 246 | switch (index) { 247 | case TEXTURE_COORDINATE_OBJECT_LINEAR: 248 | m_glState->getTexture(workingTextureCoords).coordinateGeneration = GL_OBJECT_LINEAR; 249 | break; 250 | case TEXTURE_COORDINATE_EYE_LINEAR: 251 | m_glState->getTexture(workingTextureCoords).coordinateGeneration = GL_EYE_LINEAR; 252 | break; 253 | case TEXTURE_COORDINATE_SPHERE_MAP: 254 | m_glState->getTexture(workingTextureCoords).coordinateGeneration = GL_SPHERE_MAP; 255 | break; 256 | case TEXTURE_COORDINATE_REFLECTION_MAP: 257 | m_glState->getTexture(workingTextureCoords).coordinateGeneration = GL_REFLECTION_MAP; 258 | break; 259 | case TEXTURE_COORDINATE_NORMAL_MAP: 260 | m_glState->getTexture(workingTextureCoords).coordinateGeneration = GL_NORMAL_MAP; 261 | break; 262 | default: 263 | break; 264 | } 265 | emit valueChanged(); 266 | } 267 | 268 | void 269 | SGOglTextureCoordNBPage::onCheckbox(int index) 270 | { 271 | m_glState->setTexGenEnable(m_texCoordSelGroup->checkedId() != -1); 272 | switch (index) { 273 | case 0: 274 | m_glState->getTexture(0).texGen = m_tex0TexGenEnableCheckBox->isChecked(); 275 | break; 276 | case 1: 277 | m_glState->getTexture(1).texGen = m_tex1TexGenEnableCheckBox->isChecked(); 278 | break; 279 | case 2: 280 | m_glState->getTexture(2).texGen = m_tex2TexGenEnableCheckBox->isChecked(); 281 | break; 282 | case 3: 283 | m_glState->getTexture(3).texGen = m_tex3TexGenEnableCheckBox->isChecked(); 284 | break; 285 | case 4: 286 | m_glState->getTexture(4).texGen = m_tex4TexGenEnableCheckBox->isChecked(); 287 | break; 288 | } 289 | emit valueChanged(); 290 | } 291 | 292 | void 293 | SGOglTextureCoordNBPage::onTextEnterEyeCoeffS() 294 | { 295 | QVector4D eyePlaneSVec = m_eyePlaneCoeffTextS->getValue(); 296 | 297 | m_glState->getTexture(m_texCoordUnitGroup->checkedId()).eyePlaneCoeffS = eyePlaneSVec; 298 | 299 | emit valueChanged(); 300 | } 301 | 302 | void 303 | SGOglTextureCoordNBPage::onTextEnterEyeCoeffT() 304 | { 305 | QVector4D eyePlaneTVec = m_eyePlaneCoeffTextT->getValue(); 306 | 307 | m_glState->getTexture(m_texCoordUnitGroup->checkedId()).eyePlaneCoeffT = eyePlaneTVec; 308 | 309 | emit valueChanged(); 310 | } 311 | 312 | void 313 | SGOglTextureCoordNBPage::onTextEnterObjCoeffS() 314 | { 315 | QVector4D objPlaneSVec = m_objectPlaneCoeffTextS->getValue(); 316 | 317 | m_glState->getTexture(m_texCoordUnitGroup->checkedId()).objectPlaneCoeffS = objPlaneSVec; 318 | 319 | emit valueChanged(); 320 | } 321 | 322 | void 323 | SGOglTextureCoordNBPage::onTextEnterObjCoeffT() 324 | { 325 | QVector4D objPlaneTVec = m_objectPlaneCoeffTextT->getValue(); 326 | 327 | m_glState->getTexture(m_texCoordUnitGroup->checkedId()).objectPlaneCoeffT = objPlaneTVec; 328 | 329 | emit valueChanged(); 330 | } 331 | 332 | void 333 | SGOglTextureCoordNBPage::updateWidgets() 334 | { 335 | const Texture& texture = m_glState->getTexture(m_texCoordUnitGroup->checkedId()); 336 | 337 | switch (texture.coordinateGeneration) { 338 | case GL_OBJECT_LINEAR: 339 | m_coordGenGroup->button(TEXTURE_COORDINATE_OBJECT_LINEAR)->setChecked(true); 340 | break; 341 | case GL_EYE_LINEAR: 342 | m_coordGenGroup->button(TEXTURE_COORDINATE_EYE_LINEAR)->setChecked(true); 343 | break; 344 | case GL_SPHERE_MAP: 345 | m_coordGenGroup->button(TEXTURE_COORDINATE_SPHERE_MAP)->setChecked(true); 346 | break; 347 | case GL_REFLECTION_MAP: 348 | m_coordGenGroup->button(TEXTURE_COORDINATE_REFLECTION_MAP)->setChecked(true); 349 | break; 350 | case GL_NORMAL_MAP: 351 | m_coordGenGroup->button(TEXTURE_COORDINATE_NORMAL_MAP)->setChecked(true); 352 | break; 353 | default: 354 | break; 355 | } 356 | 357 | m_eyePlaneCoeffTextS->setValue(texture.eyePlaneCoeffS); 358 | m_eyePlaneCoeffTextT->setValue(texture.eyePlaneCoeffT); 359 | m_objectPlaneCoeffTextS->setValue(texture.objectPlaneCoeffS); 360 | m_objectPlaneCoeffTextT->setValue(texture.objectPlaneCoeffT); 361 | } 362 | -------------------------------------------------------------------------------- /source/SGOglTextureCoordNBPage.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | class SGFixedGLState; 46 | class QVectorEdit; 47 | 48 | class SGOglTextureCoordNBPage : public QWidget 49 | { 50 | Q_OBJECT 51 | public: 52 | SGOglTextureCoordNBPage(SGFixedGLState* m_glState, QWidget* parent); 53 | 54 | void setup(); 55 | signals: 56 | void valueChanged(); 57 | private slots: 58 | void onRadioTexCoordGen(int index); 59 | void onRadioTextureCoordUnit(int index); 60 | void onCheckbox(int index); 61 | void onTextEnterEyeCoeffS(); 62 | void onTextEnterEyeCoeffT(); 63 | void onTextEnterObjCoeffS(); 64 | void onTextEnterObjCoeffT(); 65 | 66 | private: 67 | enum TextureCoordinateGenerationMethod 68 | { 69 | TEXTURE_COORDINATE_OBJECT_LINEAR = 0, 70 | TEXTURE_COORDINATE_EYE_LINEAR, 71 | TEXTURE_COORDINATE_SPHERE_MAP, 72 | TEXTURE_COORDINATE_REFLECTION_MAP, 73 | TEXTURE_COORDINATE_NORMAL_MAP 74 | }; 75 | 76 | SGFixedGLState* m_glState; 77 | 78 | QCheckBox *m_tex0TexGenEnableCheckBox, *m_tex1TexGenEnableCheckBox, *m_tex2TexGenEnableCheckBox, 79 | *m_tex3TexGenEnableCheckBox, *m_tex4TexGenEnableCheckBox; 80 | 81 | QButtonGroup *m_coordGenGroup, *m_texCoordSelGroup, *m_texCoordUnitGroup; 82 | 83 | QVectorEdit *m_eyePlaneCoeffTextS, *m_eyePlaneCoeffTextT, *m_objectPlaneCoeffTextS, 84 | *m_objectPlaneCoeffTextT; 85 | 86 | void updateWidgets(); 87 | }; 88 | -------------------------------------------------------------------------------- /source/SGOglTextureEnvNBPage.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | class SGFixedGLState; 46 | class QColorButton; 47 | 48 | class SGOglTextureEnvNBPage : public QWidget 49 | { 50 | Q_OBJECT 51 | public: 52 | SGOglTextureEnvNBPage(SGFixedGLState* m_glState, QWidget* parent); 53 | 54 | void setup(); 55 | signals: 56 | void valueChanged(); 57 | private slots: 58 | void onRadioTexApply(); 59 | void onRadioTextureNum(); 60 | void onCheckbox(int index); 61 | 62 | void onChoiceTextureChoose(); 63 | void onChoiceTextureCombineMode(); 64 | void onChoiceTextureCombineOperandArg0(); 65 | void onChoiceTextureCombineOperandArg1(); 66 | void onChoiceTextureCombineOperandArg2(); 67 | void onChoiceTextureCombineScale(); 68 | void onChoiceTextureCombineSrc0RGB(); 69 | void onChoiceTextureCombineSrc1RGB(); 70 | void onChoiceTextureCombineSrc2RGB(); 71 | 72 | void onButton(); 73 | 74 | private: 75 | enum TextureApplicationMethod 76 | { 77 | TEXTURE_APPLICATION_METHOD_REPLACE = 0, 78 | TEXTURE_APPLICATION_METHOD_MODULATE, 79 | TEXTURE_APPLICATION_METHOD_DECAL, 80 | TEXTURE_APPLICATION_METHOD_BLEND, 81 | TEXTURE_APPLICATION_METHOD_ADD, 82 | TEXTURE_APPLICATION_METHOD_COMBINE 83 | }; 84 | 85 | enum TextureCombineMode 86 | { 87 | COMBINE_MODE_REPLACE = 0, 88 | COMBINE_MODE_MODULATE, 89 | COMBINE_MODE_ADD, 90 | COMBINE_MODE_ADD_SIGNED, 91 | COMBINE_MODE_INTERPOLATE, 92 | COMBINE_MODE_SUBTRACT, 93 | COMBINE_MODE_DOT3_RGB, 94 | COMBINE_MODE_DOT3_RGBA 95 | }; 96 | 97 | enum TextureCombineSource 98 | { 99 | COMBINE_SOURCE_TEXTURE = 0, 100 | COMBINE_SOURCE_CONSTANT, 101 | COMBINE_SOURCE_PRIMARY_COLOR, 102 | COMBINE_SOURCE_PREVIOUS 103 | }; 104 | 105 | enum TextureCombineOperand 106 | { 107 | COMBINE_OPERAND_SRC_COLOR = 0, 108 | COMBINE_OPERAND_ONE_MINUS_SRC_COLOR, 109 | COMBINE_OPERAND_SRC_ALPHA, 110 | COMBINE_OPERAND_ONE_MINUS_SRC_ALPHA 111 | }; 112 | 113 | enum TextureCombineScale 114 | { 115 | COMBINE_SCALE_1_0 = 0, 116 | COMBINE_SCALE_2_0, 117 | COMBINE_SCALE_4_0 118 | }; 119 | 120 | void disableCombine(); 121 | void enableCombine(); 122 | 123 | SGFixedGLState* m_glState; 124 | 125 | QButtonGroup *m_texApplyGroup, *m_textureGroup, *m_texCheckBoxGroup; 126 | 127 | QCheckBox *m_tex0CheckBox, *m_tex1CheckBox, *m_tex2CheckBox, *m_tex3CheckBox, *m_tex4CheckBox; 128 | 129 | QComboBox *m_texChoose, *m_texCombineModeChoose, *m_texCombineScaleChoose, 130 | *m_texCombineSrc0RGBChoose, *m_texCombineSrc1RGBChoose, *m_texCombineSrc2RGBChoose, 131 | *m_texCombineOperandArg0Choose, *m_texCombineOperandArg1Choose, 132 | *m_texCombineOperandArg2Choose; 133 | 134 | QColorButton* m_texEnvColorButton; 135 | }; 136 | -------------------------------------------------------------------------------- /source/SGShaderGenerator.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | 42 | #include "globals.h" 43 | 44 | class SGFixedGLState; 45 | 46 | class SGShaderGenerator 47 | { 48 | public: 49 | SGShaderGenerator(const SGFixedGLState* state); 50 | ~SGShaderGenerator() = default; 51 | QString buildVertexShader() const; 52 | QString buildFragmentShader() const; 53 | 54 | private: 55 | SGFixedGLState* m_glState; 56 | 57 | void buildFragFog(QString& str) const; 58 | void buildFragTex(QString& str) const; 59 | 60 | void buildFragSeparateSpecularColor(QString& str) const; 61 | 62 | void buildLightCode(QString& str, 63 | bool& fLightPoint, 64 | bool& fLightSpot, 65 | bool& fLightDir, 66 | bool& fLightDirSpot) const; 67 | void buildVertMain(QString& str) const; 68 | void buildFuncFnormal(QString& str) const; 69 | void buildFuncFog(QString& str) const; 70 | void buildFuncPoint(QString& str) const; 71 | void buildTexCoord(QString& str, bool& fMapReflection, bool& fMapSphere) const; 72 | 73 | void addFuncLightDirectional(QString& str) const; 74 | void addFuncLightPoint(QString& str) const; 75 | void addFuncLightSpot(QString& str) const; 76 | void addFuncSphereMap(QString& str) const; 77 | void addFuncReflectionMap(QString& str) const; 78 | void addFuncLightSpotDirection(QString& str) const; 79 | }; 80 | -------------------------------------------------------------------------------- /source/SGShaderTextWindow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "QCodeEditor.h" 6 | #include "SGCanvas.h" 7 | #include "SGFrame.h" 8 | #include "SGShaderTextWindow.h" 9 | 10 | SGShaderTextWindow::SGShaderTextWindow(SGFrame* frame) 11 | : QFrame(frame) 12 | , m_frame(frame) 13 | { 14 | m_notebook = new QTabWidget(this); 15 | 16 | m_textBoxVert = new QCodeEditor(m_notebook); 17 | m_textBoxFrag = new QCodeEditor(m_notebook); 18 | m_textBoxInfo = new QTextEdit(m_notebook); 19 | 20 | QFont fixedFont("Monospace"); 21 | fixedFont.setStyleHint(QFont::TypeWriter); 22 | 23 | m_textBoxVert->setFont(fixedFont); 24 | m_textBoxFrag->setFont(fixedFont); 25 | m_textBoxInfo->setFont(fixedFont); 26 | 27 | m_notebook->addTab(m_textBoxVert, "Vertex Shader"); 28 | m_notebook->addTab(m_textBoxFrag, "Fragment Shader"); 29 | m_notebook->addTab(m_textBoxInfo, "InfoLog"); 30 | 31 | auto topSizer = new QVBoxLayout(); 32 | auto button_sizer = new QHBoxLayout(); 33 | 34 | auto pb = new QPushButton("1. GENERATE SHADERS", this); 35 | connect(pb, SIGNAL(clicked()), SLOT(generateClicked())); 36 | button_sizer->addWidget(pb); 37 | 38 | pb = new QPushButton("2. COMPILE", this); 39 | connect(pb, SIGNAL(clicked()), SLOT(compileClicked())); 40 | button_sizer->addWidget(pb); 41 | 42 | pb = new QPushButton("3. LINK", this); 43 | connect(pb, SIGNAL(clicked()), SLOT(linkClicked())); 44 | button_sizer->addWidget(pb); 45 | 46 | pb = new QPushButton("BUILD", this); 47 | connect(pb, SIGNAL(clicked()), SLOT(buildClicked())); 48 | button_sizer->addWidget(pb); 49 | 50 | pb = new QPushButton("CLEAR INFO LOG", this); 51 | connect(pb, SIGNAL(clicked()), SLOT(clearLog())); 52 | button_sizer->addWidget(pb); 53 | 54 | topSizer->addWidget(m_notebook); 55 | topSizer->addLayout(button_sizer); 56 | 57 | setLayout(topSizer); 58 | } 59 | 60 | void 61 | SGShaderTextWindow::generateClicked() 62 | { 63 | m_textBoxFrag->setPlainText(m_frame->getFragmentShader()); 64 | m_textBoxVert->setPlainText(m_frame->getVertexShader()); 65 | } 66 | 67 | void 68 | SGShaderTextWindow::compileClicked() 69 | { 70 | const QString vert = m_textBoxVert->toPlainText(); 71 | const QString frag = m_textBoxFrag->toPlainText(); 72 | 73 | m_frame->getCanvas()->compileShaders(vert, frag); 74 | 75 | m_notebook->setCurrentWidget(m_textBoxInfo); 76 | } 77 | 78 | void 79 | SGShaderTextWindow::linkClicked() 80 | { 81 | const QString vert = m_textBoxVert->toPlainText(); 82 | const QString frag = m_textBoxFrag->toPlainText(); 83 | const bool hasLinked = m_frame->getCanvas()->linkShaders(vert, frag); 84 | m_notebook->setCurrentWidget(m_textBoxInfo); 85 | if (hasLinked) { 86 | m_frame->setCanvasMode(SGCanvas::GLModeChoiceShader); 87 | } 88 | 89 | m_textBoxInfo->textCursor().movePosition(QTextCursor::End); 90 | } 91 | 92 | void 93 | SGShaderTextWindow::buildClicked() 94 | { 95 | const QString vert = m_textBoxVert->toPlainText(); 96 | const QString frag = m_textBoxFrag->toPlainText(); 97 | 98 | const bool hasLinked = m_frame->getCanvas()->linkShaders(vert, frag); 99 | if (hasLinked) { 100 | m_notebook->setCurrentWidget(m_textBoxInfo); 101 | m_frame->setCanvasMode(SGCanvas::GLModeChoiceShader); 102 | } 103 | m_textBoxInfo->textCursor().movePosition(QTextCursor::End); 104 | } 105 | 106 | void 107 | SGShaderTextWindow::log(const QString& text) 108 | { 109 | m_textBoxInfo->textCursor().movePosition(QTextCursor::End); 110 | m_textBoxInfo->append(text); 111 | } 112 | 113 | void 114 | SGShaderTextWindow::clearLog() 115 | { 116 | m_textBoxInfo->clear(); 117 | } 118 | -------------------------------------------------------------------------------- /source/SGShaderTextWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class SGFrame; 8 | 9 | class SGShaderTextWindow : public QFrame 10 | { 11 | Q_OBJECT 12 | public: 13 | SGShaderTextWindow(SGFrame* frame); 14 | void setVertexShaderText(const QString& text) { m_textBoxVert->setPlainText(text); } 15 | void setFragmentShaderText(const QString& text) { m_textBoxFrag->setPlainText(text); } 16 | 17 | public slots: 18 | void log(const QString& text); 19 | void clearLog(); 20 | private slots: 21 | void generateClicked(); 22 | void compileClicked(); 23 | void linkClicked(); 24 | void buildClicked(); 25 | 26 | private: 27 | SGFrame* m_frame; 28 | QPlainTextEdit *m_textBoxVert, *m_textBoxFrag; 29 | QTextEdit* m_textBoxInfo; 30 | QTabWidget* m_notebook; 31 | }; 32 | -------------------------------------------------------------------------------- /source/SGSurfaces.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #include "SGSurfaces.h" 39 | 40 | #define _USE_MATH_DEFINES 41 | #include 42 | #include 43 | 44 | static const float TWO_PI = 6.28318530717958647692f; 45 | 46 | TParametricSurface::TParametricSurface() 47 | : m_slices(100) 48 | {} 49 | 50 | void 51 | TParametricSurface::generate() 52 | { 53 | const int stacks = m_slices / 2; 54 | m_du = 1.0f / (float)(m_slices - 1); 55 | m_dv = 1.0f / (float)(stacks - 1); 56 | 57 | m_normals.reserve(2 * m_slices * stacks); 58 | m_texCoords.reserve(2 * m_slices * stacks); 59 | m_vertices.reserve(2 * m_slices * stacks); 60 | 61 | for (int i = 0; i < m_slices; i++) { 62 | const float u = i * m_du; 63 | m_flipped = flip(QVector2D(u, 0)); 64 | 65 | for (int j = 0; j < stacks; j++) { 66 | const float v = j * m_dv; 67 | QVector3D normal, p0; 68 | 69 | QVector2D domain = m_flipped ? QVector2D(u + m_du, v) : QVector2D(u, v); 70 | vertex(domain, normal, p0); 71 | m_normals.push_back(normal); 72 | m_texCoords.push_back(domain); 73 | m_vertices.push_back(p0); 74 | 75 | domain = m_flipped ? QVector2D(u, v) : QVector2D(u + m_du, v); 76 | vertex(domain, normal, p0); 77 | m_normals.push_back(normal); 78 | m_texCoords.push_back(domain); 79 | m_vertices.push_back(p0); 80 | } 81 | } 82 | } 83 | 84 | // Send out a normal, texture coordinate, vertex coordinate, and an optional 85 | // custom attribute. 86 | void 87 | TParametricSurface::vertex(QVector2D& domain, QVector3D& normal, QVector3D& p0) const 88 | { 89 | QVector3D p1, p2, p3; 90 | const float u = domain.x(); 91 | const float v = domain.y(); 92 | 93 | eval(domain, p0); 94 | QVector2D z1(u + m_du / 2, v); 95 | eval(z1, p1); 96 | QVector2D z2(u + m_du / 2 + m_du, v); 97 | eval(z2, p3); 98 | 99 | if (m_flipped) { 100 | QVector2D z3(u + m_du / 2, v - m_dv); 101 | eval(z3, p2); 102 | } else { 103 | QVector2D z4(u + m_du / 2, v + m_dv); 104 | eval(z4, p2); 105 | } 106 | 107 | normal = QVector3D::crossProduct(p3 - p1, p2 - p1); 108 | if (normal.length() < 0.00001f) { 109 | normal = p0; 110 | } 111 | normal.normalize(); 112 | } 113 | 114 | void 115 | TKlein::eval(QVector2D& domain, QVector3D& range) const 116 | { 117 | const float u = (1 - domain.x()) * TWO_PI; 118 | const float v = domain.y() * TWO_PI; 119 | 120 | const float x0 = 3 * cosf(u) * (1 + sinf(u)) + (2 * (1 - cosf(u) / 2)) * cosf(u) * cosf(v); 121 | const float y0 = 8 * sinf(u) + (2 * (1 - cosf(u) / 2)) * sinf(u) * cosf(v); 122 | 123 | const float x1 = 3 * cosf(u) * (1 + sinf(u)) + (2 * (1 - cosf(u) / 2)) * cosf(v + M_PI); 124 | const float y1 = 8 * sinf(u); 125 | 126 | range.setX(u < M_PI ? x0 : x1); 127 | range.setY(u < M_PI ? y0 : y1); 128 | range.setZ((2 * (1 - cosf(u) / 2)) * sinf(v)); 129 | range = range / 10; 130 | range.setY(-range.y()); 131 | 132 | // Tweak the texture coordinates. 133 | domain.setX(domain.x() * 4); 134 | } 135 | 136 | // Flip the normals along a segment of the Klein bottle so that we don't need 137 | // two-sided lighting. 138 | bool 139 | TKlein::flip(const QVector2D& domain) const 140 | { 141 | return (domain.x() < .125); 142 | } 143 | 144 | void 145 | TTrefoil::eval(QVector2D& domain, QVector3D& range) const 146 | { 147 | const float a = 0.5f; 148 | const float b = 0.3f; 149 | const float c = 0.5f; 150 | const float d = 0.1f; 151 | const float u = (1 - domain.x()) * TWO_PI * 2; 152 | const float v = domain.y() * TWO_PI; 153 | 154 | const float r = a + b * cosf(1.5f * u); 155 | const float x = r * cosf(u); 156 | const float y = r * sinf(u); 157 | const float z = c * sinf(1.5f * u); 158 | 159 | QVector3D dv; 160 | dv.setX(-1.5f * b * sinf(1.5f * u) * cosf(u) - (a + b * cosf(1.5f * u)) * sinf(u)); 161 | dv.setY(-1.5f * b * sinf(1.5f * u) * sinf(u) + (a + b * cosf(1.5f * u)) * cosf(u)); 162 | dv.setZ(1.5f * c * cosf(1.5f * u)); 163 | 164 | QVector3D q = dv; 165 | q.normalize(); 166 | QVector3D qvn(q.y(), -q.x(), 0); 167 | qvn.normalize(); 168 | QVector3D ww = QVector3D::crossProduct(q, qvn); 169 | 170 | range.setX(x + d * (qvn.x() * cosf(v) + ww.x() * sinf(v))); 171 | range.setY(y + d * (qvn.y() * cosf(v) + ww.y() * sinf(v))); 172 | range.setZ(z + d * ww.z() * sinf(v)); 173 | 174 | // Tweak the texture coordinates. 175 | domain.setX(domain.x() * 20); 176 | domain /= 3; 177 | } 178 | 179 | void 180 | TConic::eval(QVector2D& domain, QVector3D& range) const 181 | { 182 | const float a = 0.2f; 183 | const float b = 1.5f; 184 | const float c = 0.1f; 185 | const float n = 2; 186 | 187 | const float u = domain.x() * TWO_PI; 188 | const float v = domain.y() * TWO_PI; 189 | 190 | range.setX(a * (1 - v / TWO_PI) * cosf(n * v) * (1 + cosf(u)) + c * cosf(n * v)); 191 | range.setZ(a * (1 - v / TWO_PI) * sinf(n * v) * (1 + cosf(u)) + c * sinf(n * v)); 192 | range.setY(b * v / TWO_PI + a * (1 - v / TWO_PI) * sinf(u) - 0.7f); 193 | range *= 1.25; 194 | range.setY(range.y() + 0.125); 195 | 196 | // Tweak the texture coordinates. 197 | domain.setY(domain.y() * 4); 198 | } 199 | 200 | void 201 | TTorus::eval(QVector2D& domain, QVector3D& range) const 202 | { 203 | const float major = 0.8f; 204 | const float minor = 0.2f; 205 | const float u = domain.x() * TWO_PI; 206 | const float v = domain.y() * TWO_PI; 207 | 208 | range.setX((major + minor * cosf(v)) * cosf(u)); 209 | range.setY((major + minor * cosf(v)) * sinf(u)); 210 | range.setZ(minor * sinf(v)); 211 | 212 | // Tweak the texture coordinates. 213 | domain.setX(domain.x() * 4); 214 | } 215 | 216 | void 217 | TSphere::eval(QVector2D& domain, QVector3D& range) const 218 | { 219 | const float radius = 1; 220 | const float u = std::abs(domain.y() * M_PI); 221 | const float v = std::abs(domain.x() * TWO_PI); 222 | 223 | range.setX(radius * cosf(v) * sinf(u)); 224 | range.setZ(radius * sinf(v) * sinf(u)); 225 | range.setY(radius * cosf(u)); 226 | 227 | domain.setY(1 - domain.y()); 228 | domain.setX(1 - domain.x()); 229 | } 230 | 231 | void 232 | TPlane::eval(QVector2D& domain, QVector3D& range) const 233 | { 234 | if (m_z < 0) { 235 | range.setX(-m_width * (domain.x() - 0.5f)); 236 | range.setY(m_width * (domain.y() - 0.5f)); 237 | } else { 238 | range.setX(m_width * (domain.x() - 0.5f)); 239 | range.setY(m_width * (domain.y() - 0.5f)); 240 | } 241 | range.setZ(m_z); 242 | } 243 | -------------------------------------------------------------------------------- /source/SGSurfaces.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | // Abstract base class representing a parametric surface. 45 | class TParametricSurface 46 | { 47 | public: 48 | TParametricSurface(); 49 | virtual ~TParametricSurface() = default; 50 | 51 | void generate(); 52 | 53 | int slices() const { return m_slices; } 54 | const QVector& vertices() const { return m_vertices; } 55 | const QVector& normals() const { return m_normals; } 56 | const QVector& texCoords() const { return m_texCoords; } 57 | 58 | protected: 59 | virtual void eval(QVector2D& domain, QVector3D& range) const = 0; 60 | virtual void vertex(QVector2D& domain, QVector3D& normal, QVector3D& p0) const; 61 | virtual bool flip(const QVector2D& /*domain*/) const { return false; } 62 | 63 | int m_slices; 64 | bool m_flipped; 65 | float m_du, m_dv; 66 | QVector m_vertices; 67 | QVector m_normals; 68 | QVector m_texCoords; 69 | }; 70 | 71 | class TSphere : public TParametricSurface 72 | { 73 | public: 74 | void eval(QVector2D& domain, QVector3D& range) const; 75 | }; 76 | 77 | class TTorus : public TParametricSurface 78 | { 79 | public: 80 | void eval(QVector2D& domain, QVector3D& range) const; 81 | }; 82 | 83 | class TConic : public TParametricSurface 84 | { 85 | public: 86 | void eval(QVector2D& domain, QVector3D& range) const; 87 | }; 88 | 89 | class TTrefoil : public TParametricSurface 90 | { 91 | public: 92 | void eval(QVector2D& domain, QVector3D& range) const; 93 | }; 94 | 95 | class TKlein : public TParametricSurface 96 | { 97 | public: 98 | void eval(QVector2D& domain, QVector3D& range) const; 99 | bool flip(const QVector2D& domain) const; 100 | }; 101 | 102 | class TPlane : public TParametricSurface 103 | { 104 | public: 105 | TPlane(float z = 0, float width = 2) 106 | : m_z(z) 107 | , m_width(width) 108 | {} 109 | void eval(QVector2D& domain, QVector3D& range) const; 110 | 111 | protected: 112 | float m_z, m_width; 113 | }; 114 | -------------------------------------------------------------------------------- /source/SGTextures.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #include 39 | #include 40 | 41 | #include "SGFixedGLState.h" 42 | #include "SGFrame.h" 43 | #include "SGTextures.h" 44 | 45 | #include 46 | 47 | #include 48 | #include 49 | 50 | SGTextures::SGTextures(SGFrame* frame, SGFixedGLState* state) 51 | : m_frame(frame) 52 | , m_glState(state) 53 | { 54 | m_textureNames << "3Dlabs"; 55 | m_textureNames << "3DlabsNormal"; 56 | m_textureNames << "rust"; 57 | m_textureNames << "Leopard"; 58 | m_textureNames << "eyeball"; 59 | m_textureNames << "cobblestonesDiffuse"; 60 | m_textureNames << "cobblestonesNormal"; 61 | m_textureNames << "bricksDiffuse"; 62 | m_textureNames << "bricksNormal"; 63 | m_textureNames << "stonewallDiffuse"; 64 | m_textureNames << "stonewallNormal"; 65 | m_textureNames << "metalSheetDiffuse"; 66 | m_textureNames << "metalSheetNormal"; 67 | 68 | m_textures.resize(m_textureNames.size()); 69 | } 70 | 71 | void 72 | SGTextures::bind(int id, int unit) 73 | { 74 | initializeOpenGLFunctions(); 75 | 76 | if (!m_textures[id]) { 77 | const QImage image = QImage(":/textures/" + m_textureNames[id] + ".png").mirrored(); 78 | if (image.isNull()) { 79 | QMessageBox::critical(m_frame, 80 | "GLSL ShaderGen", 81 | QString("Unable to load image %1").arg(m_textureNames[id])); 82 | return; 83 | } 84 | m_textures[id] = new QOpenGLTexture(image, QOpenGLTexture::GenerateMipMaps); 85 | m_textures[id]->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); 86 | m_textures[id]->setMagnificationFilter(QOpenGLTexture::Linear); 87 | m_textures[id]->setWrapMode(QOpenGLTexture::Repeat); 88 | } 89 | 90 | PrintOpenGLError(); 91 | 92 | glActiveTexture(GL_TEXTURE0 + unit); 93 | 94 | const Texture& texture = m_glState->getTexture(unit); 95 | 96 | PrintOpenGLError(); 97 | 98 | glDisable(GL_TEXTURE_GEN_S); 99 | glDisable(GL_TEXTURE_GEN_T); 100 | PrintOpenGLError(); 101 | 102 | if (texture.texGen) { 103 | glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, texture.coordinateGeneration); 104 | glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, texture.coordinateGeneration); 105 | PrintOpenGLError(); 106 | if (texture.coordinateGeneration == GL_OBJECT_LINEAR) { 107 | glTexGen(GL_S, GL_OBJECT_PLANE, texture.objectPlaneCoeffS); 108 | glTexGen(GL_T, GL_OBJECT_PLANE, texture.objectPlaneCoeffT); 109 | } 110 | PrintOpenGLError(); 111 | if (texture.coordinateGeneration == GL_EYE_LINEAR) { 112 | PrintOpenGLError(); 113 | glTexGen(GL_S, GL_EYE_PLANE, texture.eyePlaneCoeffS); 114 | PrintOpenGLError(); 115 | glTexGen(GL_T, GL_EYE_PLANE, texture.eyePlaneCoeffT); 116 | } 117 | PrintOpenGLError(); 118 | glEnable(GL_TEXTURE_GEN_S); 119 | glEnable(GL_TEXTURE_GEN_T); 120 | } 121 | 122 | PrintOpenGLError(); 123 | 124 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture.applicationMethod); 125 | 126 | glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texture.texEnvColor); 127 | 128 | PrintOpenGLError(); 129 | 130 | if (texture.applicationMethod == GL_COMBINE) { 131 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, texture.combineMode); 132 | glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, texture.combineSource0); 133 | glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, texture.combineSource1); 134 | glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, texture.combineSource2); 135 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, texture.combineOperand0); 136 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, texture.combineOperand1); 137 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, texture.combineOperand2); 138 | glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, texture.combineScale); 139 | } 140 | 141 | glEnable(GL_TEXTURE_2D); 142 | 143 | m_textures[id]->bind(unit); 144 | } 145 | 146 | void 147 | SGTextures::release(int unit) 148 | { 149 | initializeOpenGLFunctions(); 150 | 151 | glActiveTexture(GL_TEXTURE0 + unit); 152 | glDisable(GL_TEXTURE_2D); 153 | } 154 | 155 | void 156 | SGTextures::glTexEnv(GLenum target, GLenum pname, const QColor& c) 157 | { 158 | const std::array color = { 159 | (GLfloat)c.redF(), (GLfloat)c.greenF(), (GLfloat)c.blueF(), 1.f 160 | }; 161 | glTexEnvfv(target, pname, color.data()); 162 | } 163 | 164 | void 165 | SGTextures::glTexGen(GLenum coord, GLenum pname, const QVector4D& v) 166 | { 167 | const std::array vector = { v.x(), v.y(), v.z(), v.w() }; 168 | glTexGenfv(coord, pname, vector.data()); 169 | } 170 | -------------------------------------------------------------------------------- /source/SGTextures.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | class QOpenGLTexture; 47 | 48 | class SGFixedGLState; 49 | class SGFrame; 50 | 51 | class SGTextures : protected QOpenGLFunctions_2_1 52 | { 53 | public: 54 | SGTextures(SGFrame* frame, SGFixedGLState* state); 55 | ~SGTextures() = default; 56 | 57 | const QStringList& getTextureNames() const { return m_textureNames; } 58 | 59 | void bind(int id, int unit); 60 | void release(int unit); 61 | 62 | private: 63 | void glTexEnv(GLenum target, GLenum pname, const QColor& c); 64 | void glTexGen(GLenum coord, GLenum pname, const QVector4D& v); 65 | 66 | SGFrame* m_frame; 67 | SGFixedGLState* m_glState; 68 | QVector m_textures; 69 | QStringList m_textureNames; 70 | }; 71 | -------------------------------------------------------------------------------- /source/SgFrame.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 800 10 | 600 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 21 | Qt::Vertical 22 | 23 | 24 | 25 | Qt::Horizontal 26 | 27 | 28 | 29 | QFrame::StyledPanel 30 | 31 | 32 | QFrame::Raised 33 | 34 | 35 | 36 | 37 | QFrame::StyledPanel 38 | 39 | 40 | QFrame::Raised 41 | 42 | 43 | 44 | 45 | 46 | 47 | Tab 1 48 | 49 | 50 | 51 | 52 | Tab 2 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 0 64 | 0 65 | 800 66 | 21 67 | 68 | 69 | 70 | 71 | &File 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | &View 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | &Model 89 | 90 | 91 | 92 | 93 | &Help 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | Open... 107 | 108 | 109 | 110 | 111 | Save As... 112 | 113 | 114 | 115 | 116 | Exit 117 | 118 | 119 | 120 | 121 | About... 122 | 123 | 124 | 125 | 126 | Help... 127 | 128 | 129 | 130 | 131 | Perspective 132 | 133 | 134 | 135 | 136 | Switch GL Mode 137 | 138 | 139 | 140 | 141 | 142 | SGOglNotebook 143 | QTabWidget 144 |
SGOglNotebook.h
145 | 1 146 |
147 | 148 | SGShaderTextWindow 149 | QFrame 150 |
SGShaderTextWindow.h
151 | 1 152 |
153 | 154 | SGCanvasWrapper 155 | QFrame 156 |
SGCanvasWrapper.h
157 | 1 158 |
159 |
160 | 161 | 162 |
163 | -------------------------------------------------------------------------------- /source/ShaderGen.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=ShaderGen 4 | Comment=GLSL Shader Generator 5 | Exec=ShaderGen 6 | Icon=ShaderGen 7 | Categories= 8 | -------------------------------------------------------------------------------- /source/ShaderGen.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/ShaderGen.icns -------------------------------------------------------------------------------- /source/ShaderGen.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/ShaderGen.ico -------------------------------------------------------------------------------- /source/ShaderGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/ShaderGen.png -------------------------------------------------------------------------------- /source/globals.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * Copyright (C) 2002-2005 3Dlabs Inc. Ltd. * 4 | * * 5 | * All rights reserved. * 6 | * * 7 | * Redistribution and use in source and binary forms, with or without * 8 | * modification, are permitted provided that the following conditions * 9 | * are met: * 10 | * * 11 | * Redistributions of source code must retain the above copyright * 12 | * notice, this list of conditions and the following disclaimer. * 13 | * * 14 | * Redistributions in binary form must reproduce the above * 15 | * copyright notice, this list of conditions and the following * 16 | * disclaimer in the documentation and/or other materials provided * 17 | * with the distribution. * 18 | * * 19 | * Neither the name of 3Dlabs Inc. Ltd. nor the names of its * 20 | * contributors may be used to endorse or promote products derived * 21 | * from this software without specific prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 27 | * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * 30 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 34 | * POSSIBILITY OF SUCH DAMAGE. * 35 | * * 36 | ************************************************************************/ 37 | 38 | #pragma once 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | const int NUM_TEXTURES = 5; 45 | 46 | // default values for lights 47 | const int NUM_LIGHTS_ENABLED_AT_START = 3; 48 | const int NUM_LIGHTS = 8; 49 | 50 | const QVector3D DEFAULT_LIGHT_SPOT_DIRECTION = QVector3D(0.0f, 0.0f, -1.0f); 51 | 52 | const float DEFAULT_SPOT_CUT = 180.0f; 53 | const float DEFAULT_SPOT_EXP = 0.0f; 54 | const float DEFAULT_LIGHT_CONST_ATTEN = 1.0f; 55 | const float DEFAULT_LIGHT_LINEAR_ATTEN = 0.0f; 56 | const float DEFAULT_LIGHT_QUAD_ATTEN = 0.0f; 57 | 58 | const QVector4D DEFAULT_LIGHT_POSITION_ONE = QVector4D(3.0f, -10.0f, 0.0f, 1.0f); 59 | const QColor DEFAULT_LIGHT_AMBIENT_COLOR_ONE = QColor::fromRgbF(0.0f, 0.0f, 0.0f, 1.0f); 60 | const QColor DEFAULT_LIGHT_DIFFUSE_COLOR_ONE = QColor::fromRgbF(1.0f, 0.0f, 0.0f, 1.0f); 61 | const QColor DEFAULT_LIGHT_SPECULAR_COLOR_ONE = QColor::fromRgbF(0.5f, 0.5f, 0.5f, 1.0f); 62 | 63 | const QVector4D DEFAULT_LIGHT_POSITION_TWO = QVector4D(-3.0f, -10.0f, 0.0f, 0.0f); 64 | const QColor DEFAULT_LIGHT_AMBIENT_COLOR_TWO = QColor::fromRgbF(0.0f, 0.0f, 0.0f, 1.0f); 65 | const QColor DEFAULT_LIGHT_DIFFUSE_COLOR_TWO = QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f); 66 | const QColor DEFAULT_LIGHT_SPECULAR_COLOR_TWO = QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f); 67 | 68 | const QVector4D DEFAULT_LIGHT_POSITION_THREE = QVector4D(10.0f, 0.0f, 1.0f, 1.0f); 69 | const QColor DEFAULT_LIGHT_AMBIENT_COLOR_THREE = QColor::fromRgbF(0.0f, 0.0f, 0.0f, 1.0f); 70 | const QColor DEFAULT_LIGHT_DIFFUSE_COLOR_THREE = QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f); 71 | const QColor DEFAULT_LIGHT_SPECULAR_COLOR_THREE = QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f); 72 | 73 | const QVector4D DEFAULT_LIGHT_POSITION_OTHER = QVector4D(3.0f, 10.0f, 0.0f, 1.0f); 74 | const QColor DEFAULT_LIGHT_AMBIENT_COLOR_OTHER = QColor::fromRgbF(0.0f, 0.0f, 0.0f, 1.0f); 75 | const QColor DEFAULT_LIGHT_DIFFUSE_COLOR_OTHER = QColor::fromRgbF(1.0f, 1.0f, 0.0f, 1.0f); 76 | const QColor DEFAULT_LIGHT_SPECULAR_COLOR_OTHER = QColor::fromRgbF(0.5f, 0.5f, 0.5f, 1.0f); 77 | 78 | // default values for materials 79 | const float DEFAULT_MATERIAL_SHININESS = 30.0f; 80 | 81 | const QColor DEFAULT_MATERIAL_AMBIENT_COLOR = QColor::fromRgbF(0.0f, 0.0f, 0.0f, 1.0f); 82 | const QColor DEFAULT_MATERIAL_DIFFUSE_COLOR = QColor::fromRgbF(1.0f, 1.0f, 1.0f, 1.0f); 83 | const QColor DEFAULT_MATERIAL_SPECULAR_COLOR = QColor::fromRgbF(0.3f, 0.3f, 0.3f, 1.0f); 84 | const QColor DEFAULT_MATERIAL_EMISSION_COLOR = QColor::fromRgbF(0.3f, 0.3f, 0.3f, 1.0f); 85 | 86 | // default values for fog 87 | const float DEFAULT_FOG_DENSITY = 0.0f; 88 | const float DEFAULT_FOG_START = 5.0f; 89 | const float DEFAULT_FOG_END = 7.0f; 90 | 91 | const QColor DEFAULT_FOG_COLOR = QColor::fromRgbF(0.0f, 0.0f, 0.0f, 1.0f); 92 | 93 | // default values for textures 94 | const float DEFAULT_COMBINE_RGB_SCALE = 1.0f; 95 | 96 | const int NUM_TEXTURE_COORDS = 4; // s,t,r(p),q 97 | 98 | const QColor DEFAULT_TEX_ENV_COLOR = QColor::fromRgbF(1.0f, 1.0f, 1.0f, 1.0f); 99 | const QVector4D DEFAULT_EYE_PLANE_COEFF_S = QVector4D(1.0f, 0.0f, 0.0f, 0.0f); 100 | const QVector4D DEFAULT_EYE_PLANE_COEFF_T = QVector4D(0.0f, 1.0f, 0.0f, 0.0f); 101 | const QVector4D DEFAULT_OBJ_PLANE_COEFF_S = QVector4D(1.0f, 0.0f, 0.0f, 0.0f); 102 | const QVector4D DEFAULT_OBJ_PLANE_COEFF_T = QVector4D(0.0f, 1.0f, 0.0f, 0.0f); 103 | -------------------------------------------------------------------------------- /source/info.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "ShaderGen.ico" 2 | -------------------------------------------------------------------------------- /source/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "SGFrame.h" 5 | 6 | int 7 | main(int argc, char* argv[]) 8 | { 9 | // Force 'desktop' opengl 10 | QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); 11 | 12 | QApplication app(argc, argv); 13 | QApplication::setApplicationName("GLSL ShaderGen"); 14 | QApplication::setOrganizationName("mojocorp"); 15 | QApplication::setQuitOnLastWindowClosed(true); 16 | 17 | QSurfaceFormat format; 18 | format.setVersion(2, 1); 19 | format.setProfile(QSurfaceFormat::CompatibilityProfile); 20 | QSurfaceFormat::setDefaultFormat(format); 21 | 22 | SGFrame mainWin(QApplication::applicationName()); 23 | mainWin.resize(800, 800); 24 | mainWin.readSettings(); 25 | mainWin.show(); 26 | 27 | return app.exec(); 28 | } 29 | -------------------------------------------------------------------------------- /source/textures/3Dlabs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/3Dlabs.png -------------------------------------------------------------------------------- /source/textures/3DlabsNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/3DlabsNormal.png -------------------------------------------------------------------------------- /source/textures/Leopard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/Leopard.png -------------------------------------------------------------------------------- /source/textures/bricksDiffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/bricksDiffuse.png -------------------------------------------------------------------------------- /source/textures/bricksNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/bricksNormal.png -------------------------------------------------------------------------------- /source/textures/cobblestonesDiffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/cobblestonesDiffuse.png -------------------------------------------------------------------------------- /source/textures/cobblestonesNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/cobblestonesNormal.png -------------------------------------------------------------------------------- /source/textures/eyeball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/eyeball.png -------------------------------------------------------------------------------- /source/textures/metalSheetDiffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/metalSheetDiffuse.png -------------------------------------------------------------------------------- /source/textures/metalSheetNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/metalSheetNormal.png -------------------------------------------------------------------------------- /source/textures/rust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/rust.png -------------------------------------------------------------------------------- /source/textures/stonewallDiffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/stonewallDiffuse.png -------------------------------------------------------------------------------- /source/textures/stonewallNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mojocorp/ShaderGen/30925949ec56b588181eecd379391f70f39388a6/source/textures/stonewallNormal.png -------------------------------------------------------------------------------- /source/textures1.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | textures/3Dlabs.png 4 | textures/3DlabsNormal.png 5 | textures/bricksDiffuse.png 6 | textures/bricksNormal.png 7 | textures/cobblestonesDiffuse.png 8 | textures/cobblestonesNormal.png 9 | 10 | 11 | -------------------------------------------------------------------------------- /source/textures2.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | textures/eyeball.png 4 | textures/Leopard.png 5 | textures/metalSheetDiffuse.png 6 | textures/metalSheetNormal.png 7 | textures/rust.png 8 | textures/stonewallDiffuse.png 9 | textures/stonewallNormal.png 10 | 11 | 12 | --------------------------------------------------------------------------------