fix: Résolution complète du problème OpenGL/ImGui avec threading
PROBLÈME RÉSOLU: Les shaders ImGui compilent maintenant avec succès!
Changements majeurs:
- Remplacé vcpkg ImGui par FetchContent (compilation from source)
- Créé wrapper GLAD pour ImGui (imgui_opengl3_glad.cpp)
- Ajout de makeContextCurrent() pour gérer le contexte OpenGL multi-thread
- Release du contexte dans initialize(), puis rendu current dans uiThread()
Root Cause Analysis:
1. Rendering s'exécute dans uiThread() (thread séparé)
2. Contexte OpenGL créé dans thread principal n'était pas accessible
3. glCreateShader retournait 0 avec GL_INVALID_OPERATION (erreur 1282)
4. Solution: Transfer du contexte OpenGL du thread principal vers uiThread
Debugging profond:
- Ajout de logs debug dans ImGui pour tracer glCreateShader
- Découvert que handle=0 indiquait échec de création (pas compilation)
- Identifié erreur WGL \"ressource en cours d'utilisation\" = contexte locked
Fichiers modifiés:
- vcpkg.json: Supprimé imgui
- CMakeLists.txt: FetchContent pour ImGui + imgui_backends library
- src/imgui_opengl3_glad.cpp: Nouveau wrapper GLAD
- src/ui/TranslationUI.{h,cpp}: Ajout makeContextCurrent()
- src/core/Pipeline.cpp: Appel makeContextCurrent() dans uiThread()
- build/.../imgui_impl_opengl3.cpp: Debug logs (temporaire)
Résultat: UI fonctionne! NVIDIA RTX 4060 GPU, OpenGL 3.3.0, shaders compilent
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ddf34db2a0
commit
7dec7a6eed
11
.claude/settings.local.json
Normal file
11
.claude/settings.local.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(timeout:*)",
|
||||
"Bash(cmake --build:*)",
|
||||
"Bash(./build_mingw.bat)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
@ -5,21 +5,51 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# FetchContent for downloading ImGui from source
|
||||
include(FetchContent)
|
||||
|
||||
# Force static linking for MinGW
|
||||
if(MINGW)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
|
||||
# Find packages
|
||||
# Fetch ImGui from GitHub (like WarFactory does!)
|
||||
FetchContent_Declare(
|
||||
imgui
|
||||
GIT_REPOSITORY https://github.com/ocornut/imgui.git
|
||||
GIT_TAG v1.90.1
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(imgui)
|
||||
|
||||
# Create ImGui library with OpenGL/GLFW backends
|
||||
add_library(imgui_backends
|
||||
${imgui_SOURCE_DIR}/imgui.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_demo.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_draw.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_tables.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/imgui_opengl3_glad.cpp # Our wrapper with GLAD
|
||||
)
|
||||
|
||||
target_include_directories(imgui_backends PUBLIC
|
||||
${imgui_SOURCE_DIR}
|
||||
${imgui_SOURCE_DIR}/backends
|
||||
)
|
||||
|
||||
# Find packages (no more vcpkg imgui!)
|
||||
find_package(portaudio CONFIG REQUIRED)
|
||||
find_package(httplib CONFIG REQUIRED)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
find_package(imgui CONFIG REQUIRED)
|
||||
find_package(glfw3 CONFIG REQUIRED)
|
||||
find_package(glad CONFIG REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
# Link imgui_backends with glfw and OpenGL
|
||||
target_link_libraries(imgui_backends PUBLIC glfw OpenGL::GL glad::glad)
|
||||
|
||||
# Source files for UI version
|
||||
set(SOURCES_UI
|
||||
src/main.cpp
|
||||
@ -73,7 +103,7 @@ if(MINGW AND NOT BUILD_SHARED_LIBS)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-mingw-static/lib/libportaudio.a
|
||||
httplib::httplib
|
||||
nlohmann_json::nlohmann_json
|
||||
imgui::imgui
|
||||
imgui_backends
|
||||
${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-mingw-static/lib/libglfw3.a
|
||||
glad::glad
|
||||
OpenGL::GL
|
||||
@ -95,7 +125,7 @@ else()
|
||||
portaudio
|
||||
httplib::httplib
|
||||
nlohmann_json::nlohmann_json
|
||||
imgui::imgui
|
||||
imgui_backends
|
||||
glfw
|
||||
glad::glad
|
||||
OpenGL::GL
|
||||
|
||||
51
CMakeLists_noui.txt
Normal file
51
CMakeLists_noui.txt
Normal file
@ -0,0 +1,51 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(SecondVoice_NoUI VERSION 0.1.0 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Find packages (NO IMGUI, NO GLFW, NO OPENGL)
|
||||
find_package(portaudio CONFIG REQUIRED)
|
||||
find_package(httplib CONFIG REQUIRED)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
|
||||
# Source files (NO UI)
|
||||
set(SOURCES
|
||||
src/main_no_ui_test.cpp
|
||||
src/audio/AudioCapture.cpp
|
||||
src/audio/AudioBuffer.cpp
|
||||
src/utils/Config.cpp
|
||||
)
|
||||
|
||||
# Executable
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
# Include directories
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Link libraries (NO IMGUI)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
portaudio
|
||||
httplib::httplib
|
||||
nlohmann_json::nlohmann_json
|
||||
)
|
||||
|
||||
# Compiler options
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
)
|
||||
|
||||
if(MINGW)
|
||||
target_link_options(${PROJECT_NAME} PRIVATE -mconsole)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Copy config files to build directory
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.json
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.json COPYONLY)
|
||||
62
CMakeLists_noui_fixed.txt
Normal file
62
CMakeLists_noui_fixed.txt
Normal file
@ -0,0 +1,62 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(SecondVoice_NoUI VERSION 0.1.0 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Find packages (NO IMGUI, NO GLFW, NO OPENGL)
|
||||
find_package(portaudio CONFIG REQUIRED)
|
||||
find_package(httplib CONFIG REQUIRED)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
|
||||
# Source files (NO UI)
|
||||
set(SOURCES
|
||||
src/main_no_ui_test.cpp
|
||||
src/audio/AudioCapture.cpp
|
||||
src/audio/AudioBuffer.cpp
|
||||
src/utils/Config.cpp
|
||||
)
|
||||
|
||||
# Executable
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
# Include directories
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Link libraries (NO IMGUI) - use static linking for MinGW
|
||||
if(MINGW)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-mingw-static/lib/libportaudio.a
|
||||
httplib::httplib
|
||||
nlohmann_json::nlohmann_json
|
||||
# Windows system libraries for portaudio
|
||||
winmm
|
||||
setupapi
|
||||
)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
portaudio
|
||||
httplib::httplib
|
||||
nlohmann_json::nlohmann_json
|
||||
)
|
||||
endif()
|
||||
|
||||
# Compiler options
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
)
|
||||
|
||||
if(MINGW)
|
||||
target_link_options(${PROJECT_NAME} PRIVATE -mconsole)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Copy config files to build directory
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.json
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.json COPYONLY)
|
||||
10
create_shortcut.ps1
Normal file
10
create_shortcut.ps1
Normal file
@ -0,0 +1,10 @@
|
||||
# Create desktop shortcut for SecondVoice
|
||||
$WshShell = New-Object -comObject WScript.Shell
|
||||
$Shortcut = $WshShell.CreateShortcut("$env:USERPROFILE\Desktop\SecondVoice.lnk")
|
||||
$Shortcut.TargetPath = Join-Path $PSScriptRoot "build\mingw-Release\SecondVoice.exe"
|
||||
$Shortcut.WorkingDirectory = Join-Path $PSScriptRoot "build\mingw-Release"
|
||||
$Shortcut.Description = "SecondVoice - Real-time Chinese to French Translation"
|
||||
$Shortcut.Save()
|
||||
|
||||
Write-Host "Desktop shortcut created!" -ForegroundColor Green
|
||||
Write-Host "Double-click 'SecondVoice' on your desktop to launch" -ForegroundColor Cyan
|
||||
75
force_nvidia_gpu.ps1
Normal file
75
force_nvidia_gpu.ps1
Normal file
@ -0,0 +1,75 @@
|
||||
# Force SecondVoice to use NVIDIA GPU
|
||||
# Run as Administrator
|
||||
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Force NVIDIA GPU for SecondVoice" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Check if running as admin
|
||||
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
|
||||
if (-not $isAdmin) {
|
||||
Write-Host "WARNING: Not running as Administrator" -ForegroundColor Yellow
|
||||
Write-Host "Some settings may not apply properly" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Get the executable path
|
||||
$exePath = Join-Path $PSScriptRoot "build\mingw-Release\SecondVoice.exe"
|
||||
$exeFullPath = (Resolve-Path $exePath -ErrorAction SilentlyContinue).Path
|
||||
|
||||
if (-not $exeFullPath) {
|
||||
Write-Host "ERROR: SecondVoice.exe not found at:" -ForegroundColor Red
|
||||
Write-Host " $exePath" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Please build the project first:" -ForegroundColor Yellow
|
||||
Write-Host " .\build_mingw.bat" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Found executable:" -ForegroundColor Green
|
||||
Write-Host " $exeFullPath" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
# Method 1: Registry settings for NVIDIA Optimus
|
||||
Write-Host "Setting NVIDIA Optimus preference..." -ForegroundColor Cyan
|
||||
|
||||
$regPath = "HKCU:\Software\Microsoft\DirectX\UserGpuPreferences"
|
||||
|
||||
if (-not (Test-Path $regPath)) {
|
||||
New-Item -Path $regPath -Force | Out-Null
|
||||
}
|
||||
|
||||
# Set to use high performance GPU (NVIDIA)
|
||||
Set-ItemProperty -Path $regPath -Name $exeFullPath -Value "GpuPreference=2;" -Type String
|
||||
|
||||
Write-Host "✓ Registry setting applied" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Instructions for manual configuration
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Manual Configuration (if needed)" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "If the automatic setting does not work, configure manually:" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "Method 1 - Windows Graphics Settings:" -ForegroundColor White
|
||||
Write-Host " 1. Open Windows Settings (Win + I)" -ForegroundColor Gray
|
||||
Write-Host " 2. System > Display > Graphics" -ForegroundColor Gray
|
||||
Write-Host " 3. Click Browse and select:" -ForegroundColor Gray
|
||||
Write-Host " $exeFullPath" -ForegroundColor Cyan
|
||||
Write-Host " 4. Click Options > High performance" -ForegroundColor Gray
|
||||
Write-Host " 5. Save" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
Write-Host "Method 2 - NVIDIA Control Panel:" -ForegroundColor White
|
||||
Write-Host " 1. Right-click desktop > NVIDIA Control Panel" -ForegroundColor Gray
|
||||
Write-Host " 2. Manage 3D Settings > Program Settings" -ForegroundColor Gray
|
||||
Write-Host " 3. Add SecondVoice.exe" -ForegroundColor Gray
|
||||
Write-Host " 4. Select High-performance NVIDIA processor" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "✓ Configuration complete!" -ForegroundColor Green
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Please restart SecondVoice for changes to take effect" -ForegroundColor Yellow
|
||||
38
run_secondvoice.bat
Normal file
38
run_secondvoice.bat
Normal file
@ -0,0 +1,38 @@
|
||||
@echo off
|
||||
REM Force SecondVoice to use NVIDIA GPU
|
||||
|
||||
echo ========================================
|
||||
echo SecondVoice - Launcher
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM Set NVIDIA GPU preference
|
||||
set SHIM_MCCOMPAT=0x800000001
|
||||
set __COMPAT_LAYER=HIGHDPIAWARE
|
||||
|
||||
REM Check if .env exists
|
||||
if not exist "build\mingw-Release\.env" (
|
||||
echo [WARNING] .env file not found in build\mingw-Release\
|
||||
echo.
|
||||
echo Please create it with your API keys:
|
||||
echo OPENAI_API_KEY=sk-...
|
||||
echo ANTHROPIC_API_KEY=sk-ant-...
|
||||
echo.
|
||||
echo Press any key to continue anyway, or Ctrl+C to cancel
|
||||
pause
|
||||
)
|
||||
|
||||
echo Starting SecondVoice...
|
||||
echo Using NVIDIA GPU (if available)
|
||||
echo.
|
||||
|
||||
cd build\mingw-Release
|
||||
SecondVoice.exe
|
||||
|
||||
if %errorlevel% neq 0 (
|
||||
echo.
|
||||
echo [ERROR] SecondVoice exited with error code: %errorlevel%
|
||||
pause
|
||||
)
|
||||
|
||||
exit /b %errorlevel%
|
||||
16
set_gpu.ps1
Normal file
16
set_gpu.ps1
Normal file
@ -0,0 +1,16 @@
|
||||
# Set SecondVoice to use NVIDIA GPU
|
||||
$exePath = Join-Path $PSScriptRoot "build\mingw-Release\SecondVoice.exe"
|
||||
$exeFullPath = (Resolve-Path $exePath).Path
|
||||
|
||||
$regPath = "HKCU:\Software\Microsoft\DirectX\UserGpuPreferences"
|
||||
|
||||
if (-not (Test-Path $regPath)) {
|
||||
New-Item -Path $regPath -Force | Out-Null
|
||||
}
|
||||
|
||||
Set-ItemProperty -Path $regPath -Name $exeFullPath -Value "GpuPreference=2;" -Type String
|
||||
|
||||
Write-Host "GPU preference set to High Performance for:" -ForegroundColor Green
|
||||
Write-Host $exeFullPath -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Please restart SecondVoice" -ForegroundColor Yellow
|
||||
@ -201,6 +201,9 @@ void Pipeline::processingThread() {
|
||||
}
|
||||
|
||||
void Pipeline::uiThread() {
|
||||
// CRITICAL: Make OpenGL context current in THIS thread (not the thread that created it)
|
||||
ui_->makeContextCurrent();
|
||||
|
||||
while (running_ && !ui_->shouldClose()) {
|
||||
ui_->setRecordingDuration(recording_duration_);
|
||||
ui_->setProcessingStatus("Processing...");
|
||||
|
||||
11
src/imgui_opengl3_glad.cpp
Normal file
11
src/imgui_opengl3_glad.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
// Wrapper to compile ImGui OpenGL3 backend with GLAD
|
||||
// This file includes GLAD before ImGui's OpenGL3 backend to ensure
|
||||
// OpenGL functions are properly declared
|
||||
|
||||
#include <glad/glad.h> // MUST be first - provides OpenGL function declarations
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM // Tell ImGui we're providing our own loader
|
||||
#define GLFW_INCLUDE_NONE // Tell GLFW not to include OpenGL headers
|
||||
|
||||
// Now include the ImGui OpenGL3 implementation
|
||||
// The path is relative to imgui source directory which is in include paths
|
||||
#include <backends/imgui_impl_opengl3.cpp>
|
||||
6
src/main_absolute_minimal.cpp
Normal file
6
src/main_absolute_minimal.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include <windows.h>
|
||||
|
||||
int main() {
|
||||
MessageBoxA(NULL, "Executable works! This is absolute minimum test.", "Success", MB_OK);
|
||||
return 0;
|
||||
}
|
||||
30
src/main_minimal.cpp
Normal file
30
src/main_minimal.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <windows.h>
|
||||
|
||||
int main() {
|
||||
std::ofstream log("minimal_test.log");
|
||||
log << "Minimal test started" << std::endl;
|
||||
log.flush();
|
||||
|
||||
MessageBoxA(NULL, "Step 1: Program started", "Debug", MB_OK);
|
||||
|
||||
// Test logger
|
||||
log << "Creating logger..." << std::endl;
|
||||
log.flush();
|
||||
|
||||
MessageBoxA(NULL, "Step 2: Logger OK", "Debug", MB_OK);
|
||||
|
||||
// Test config loading
|
||||
log << "Testing config..." << std::endl;
|
||||
log.flush();
|
||||
|
||||
MessageBoxA(NULL, "Step 3: About to load config", "Debug", MB_OK);
|
||||
|
||||
log << "All tests passed" << std::endl;
|
||||
log.close();
|
||||
|
||||
MessageBoxA(NULL, "All steps completed successfully!", "Success", MB_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
37
src/main_no_ui.cpp
Normal file
37
src/main_no_ui.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include "utils/Config.h"
|
||||
|
||||
// Simple file logger
|
||||
void log_msg(const std::string& msg) {
|
||||
std::ofstream log("main_no_ui.log", std::ios::app);
|
||||
log << msg << std::endl;
|
||||
log.flush();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
log_msg("MAIN (NO UI): Entry point reached");
|
||||
MessageBoxA(NULL, "SecondVoice (NO UI) starting...", "Debug", MB_OK);
|
||||
|
||||
log_msg("About to test Config loading...");
|
||||
log_msg("Config header included");
|
||||
|
||||
secondvoice::Config& config = secondvoice::Config::getInstance();
|
||||
log_msg("Config instance obtained");
|
||||
|
||||
if (!config.load("config.json", ".env")) {
|
||||
log_msg("ERROR: Failed to load configuration");
|
||||
MessageBoxA(NULL, "Failed to load configuration!", "Error", MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_msg("Configuration loaded successfully!");
|
||||
MessageBoxA(NULL, "Config loaded successfully!", "Success", MB_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
36
src/main_no_ui_test.cpp
Normal file
36
src/main_no_ui_test.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "utils/Config.h"
|
||||
#include "audio/AudioCapture.h"
|
||||
|
||||
int main() {
|
||||
std::ofstream log("no_ui_test.log");
|
||||
log << "No UI test starting..." << std::endl;
|
||||
log.flush();
|
||||
|
||||
log << "About to get Config instance..." << std::endl;
|
||||
log.flush();
|
||||
|
||||
// Test Config
|
||||
secondvoice::Config& config = secondvoice::Config::getInstance();
|
||||
|
||||
log << "Got Config instance, about to load..." << std::endl;
|
||||
log.flush();
|
||||
|
||||
if (!config.load("config.json", ".env")) {
|
||||
log << "Failed to load config" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
log << "Config loaded OK" << std::endl;
|
||||
|
||||
// Test AudioCapture
|
||||
secondvoice::AudioCapture audio(16000, 1, 10);
|
||||
if (!audio.initialize()) {
|
||||
log << "Failed to initialize audio" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
log << "Audio initialized OK" << std::endl;
|
||||
|
||||
log << "SUCCESS - All components work without UI!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
20
src/main_skeleton.cpp
Normal file
20
src/main_skeleton.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <windows.h>
|
||||
#include <fstream>
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||
(void)hInstance;
|
||||
(void)hPrevInstance;
|
||||
(void)lpCmdLine;
|
||||
(void)nCmdShow;
|
||||
|
||||
std::ofstream log("skeleton.log");
|
||||
log << "WinMain called!" << std::endl;
|
||||
log.flush();
|
||||
|
||||
MessageBoxA(NULL, "SecondVoice skeleton works! Press OK to continue.", "Success", MB_OK);
|
||||
|
||||
log << "MessageBox shown, now exiting" << std::endl;
|
||||
log.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
10
src/startup_hook.cpp
Normal file
10
src/startup_hook.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include <fstream>
|
||||
|
||||
// This will run BEFORE main() as a static initializer
|
||||
struct StartupLogger {
|
||||
StartupLogger() {
|
||||
std::ofstream log("STARTUP.log", std::ios::trunc);
|
||||
log << "Static initializer running BEFORE main()" << std::endl;
|
||||
log.flush();
|
||||
}
|
||||
} g_startup_logger;
|
||||
18
src/test_glfw_only.cpp
Normal file
18
src/test_glfw_only.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <fstream>
|
||||
|
||||
int main() {
|
||||
std::ofstream log("test_glfw.log");
|
||||
log << "GLFW test starting..." << std::endl;
|
||||
log.flush();
|
||||
|
||||
if (!glfwInit()) {
|
||||
log << "GLFW init failed!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
log << "GLFW init SUCCESS!" << std::endl;
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
37
src/test_static_logger.cpp
Normal file
37
src/test_static_logger.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
// This mimics what we have in TranslationUI.cpp
|
||||
class UILogger {
|
||||
public:
|
||||
UILogger& operator<<(const std::string& msg) {
|
||||
buffer_ += msg;
|
||||
return *this;
|
||||
}
|
||||
UILogger& operator<<(int value) {
|
||||
buffer_ += std::to_string(value);
|
||||
return *this;
|
||||
}
|
||||
UILogger& operator<<(std::ostream& (*)(std::ostream&)) {
|
||||
std::ofstream log("ui_debug.log", std::ios::app);
|
||||
log << buffer_ << std::endl;
|
||||
buffer_.clear();
|
||||
return *this;
|
||||
}
|
||||
void flush() {}
|
||||
private:
|
||||
std::string buffer_;
|
||||
};
|
||||
|
||||
// This static object might be causing the crash!
|
||||
static UILogger g_test_log;
|
||||
|
||||
int main() {
|
||||
MessageBoxA(NULL, "If you see this, static UILogger is NOT the problem!", "Test", MB_OK);
|
||||
|
||||
g_test_log << "Test message" << std::endl;
|
||||
|
||||
MessageBoxA(NULL, "Static logger works!", "Success", MB_OK);
|
||||
return 0;
|
||||
}
|
||||
@ -5,6 +5,7 @@
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include <imgui_impl_opengl3.h>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
namespace secondvoice {
|
||||
|
||||
@ -39,11 +40,10 @@ bool TranslationUI::initialize() {
|
||||
// FORCE high-performance GPU (NVIDIA/AMD dedicated)
|
||||
std::cout << "[UI] Requesting high-performance GPU..." << std::endl;
|
||||
|
||||
// OpenGL 4.6 Core Profile to match NVIDIA driver
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
// OpenGL 3.3 - core profile
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
|
||||
// Create window
|
||||
std::cout << "[UI] Creating GLFW window (" << width_ << "x" << height_ << ")..." << std::endl;
|
||||
@ -89,12 +89,65 @@ bool TranslationUI::initialize() {
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGui_ImplGlfw_InitForOpenGL(window_, true);
|
||||
// Use GLSL 460 core to match OpenGL 4.6
|
||||
ImGui_ImplOpenGL3_Init("#version 460 core");
|
||||
|
||||
// TEST: Compile a simple shader to see REAL error messages
|
||||
std::cout << "[UI] Testing shader compilation..." << std::endl;
|
||||
const char* vertexShaderSource = R"(
|
||||
#version 130
|
||||
in vec2 Position;
|
||||
in vec2 UV;
|
||||
in vec4 Color;
|
||||
varying vec2 Frag_UV;
|
||||
varying vec4 Frag_Color;
|
||||
void main() {
|
||||
Frag_UV = UV;
|
||||
Frag_Color = Color;
|
||||
gl_Position = vec4(Position, 0, 1);
|
||||
}
|
||||
)";
|
||||
|
||||
GLuint testShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(testShader, 1, &vertexShaderSource, NULL);
|
||||
glCompileShader(testShader);
|
||||
|
||||
GLint success;
|
||||
glGetShaderiv(testShader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[1024];
|
||||
glGetShaderInfoLog(testShader, 1024, NULL, infoLog);
|
||||
std::cerr << "[UI] ==================== SHADER COMPILATION ERROR ====================" << std::endl;
|
||||
std::cerr << infoLog << std::endl;
|
||||
std::cerr << "[UI] ====================================================================" << std::endl;
|
||||
} else {
|
||||
std::cout << "[UI] Test shader compiled successfully!" << std::endl;
|
||||
}
|
||||
glDeleteShader(testShader);
|
||||
|
||||
// DEBUG: Check if GLAD loaded glCreateShader
|
||||
std::cout << "[UI] DEBUG: glCreateShader function pointer = " << (void*)glCreateShader << std::endl;
|
||||
if (glCreateShader == nullptr) {
|
||||
std::cerr << "[UI] ERROR: glCreateShader is NULL!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let ImGui auto-detect the GLSL version
|
||||
ImGui_ImplOpenGL3_Init(nullptr);
|
||||
|
||||
// CRITICAL: Release the OpenGL context from this thread
|
||||
// The UI rendering will happen in a separate thread which will call makeContextCurrent()
|
||||
std::cout << "[UI] Releasing OpenGL context from initialization thread" << std::endl;
|
||||
glfwMakeContextCurrent(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TranslationUI::makeContextCurrent() {
|
||||
if (window_) {
|
||||
std::cout << "[UI] Making OpenGL context current in thread: " << std::this_thread::get_id() << std::endl;
|
||||
glfwMakeContextCurrent(window_);
|
||||
}
|
||||
}
|
||||
|
||||
void TranslationUI::render() {
|
||||
glfwPollEvents();
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ public:
|
||||
~TranslationUI();
|
||||
|
||||
bool initialize();
|
||||
void makeContextCurrent(); // Make OpenGL context current in calling thread
|
||||
void render();
|
||||
bool shouldClose() const;
|
||||
|
||||
|
||||
59
test_opengl.cpp
Normal file
59
test_opengl.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
|
||||
int main() {
|
||||
std::cout << "=== OpenGL Diagnostics ===" << std::endl;
|
||||
|
||||
// Initialize GLFW
|
||||
if (!glfwInit()) {
|
||||
std::cerr << "Failed to initialize GLFW" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a window
|
||||
GLFWwindow* window = glfwCreateWindow(100, 100, "Test", nullptr, nullptr);
|
||||
if (!window) {
|
||||
std::cerr << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return 1;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
// Query OpenGL info
|
||||
const GLubyte* vendor = glGetString(GL_VENDOR);
|
||||
const GLubyte* renderer = glGetString(GL_RENDERER);
|
||||
const GLubyte* version = glGetString(GL_VERSION);
|
||||
|
||||
std::cout << "\nVendor: " << (vendor ? (const char*)vendor : "Unknown") << std::endl;
|
||||
std::cout << "Renderer: " << (renderer ? (const char*)renderer : "Unknown") << std::endl;
|
||||
std::cout << "Version: " << (version ? (const char*)version : "Unknown") << std::endl;
|
||||
|
||||
// Check which GPU is being used via Windows API
|
||||
std::cout << "\n=== GPU Selection Info ===" << std::endl;
|
||||
if (renderer) {
|
||||
std::string renderer_str((const char*)renderer);
|
||||
if (renderer_str.find("NVIDIA") != std::string::npos) {
|
||||
std::cout << "✓ Using NVIDIA GPU (Good!)" << std::endl;
|
||||
} else if (renderer_str.find("AMD") != std::string::npos ||
|
||||
renderer_str.find("Radeon") != std::string::npos) {
|
||||
std::cout << "⚠ Using AMD integrated GPU" << std::endl;
|
||||
std::cout << " Try forcing NVIDIA GPU via Windows Graphics Settings" << std::endl;
|
||||
} else if (renderer_str.find("Intel") != std::string::npos) {
|
||||
std::cout << "⚠ Using Intel integrated GPU" << std::endl;
|
||||
} else if (renderer_str.find("Microsoft") != std::string::npos ||
|
||||
renderer_str.find("GDI") != std::string::npos) {
|
||||
std::cout << "✗ Using Microsoft software renderer (BAD!)" << std::endl;
|
||||
std::cout << " GPU drivers may not be properly installed" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\nPress Enter to exit..." << std::endl;
|
||||
std::cin.get();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -5,10 +5,6 @@
|
||||
"portaudio",
|
||||
"cpp-httplib",
|
||||
"nlohmann-json",
|
||||
{
|
||||
"name": "imgui",
|
||||
"features": ["glfw-binding", "opengl3-binding"]
|
||||
},
|
||||
"glfw3",
|
||||
"glad",
|
||||
"opengl"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user