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:
StillHammer 2025-11-21 16:37:47 +08:00
parent ddf34db2a0
commit 7dec7a6eed
22 changed files with 624 additions and 14 deletions

View File

@ -0,0 +1,11 @@
{
"permissions": {
"allow": [
"Bash(timeout:*)",
"Bash(cmake --build:*)",
"Bash(./build_mingw.bat)"
],
"deny": [],
"ask": []
}
}

View File

@ -5,21 +5,51 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# FetchContent for downloading ImGui from source
include(FetchContent)
# Force static linking for MinGW # Force static linking for MinGW
if(MINGW) if(MINGW)
set(BUILD_SHARED_LIBS OFF) set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif() 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(portaudio CONFIG REQUIRED)
find_package(httplib CONFIG REQUIRED) find_package(httplib CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED) find_package(nlohmann_json CONFIG REQUIRED)
find_package(imgui CONFIG REQUIRED)
find_package(glfw3 CONFIG REQUIRED) find_package(glfw3 CONFIG REQUIRED)
find_package(glad CONFIG REQUIRED) find_package(glad CONFIG REQUIRED)
find_package(OpenGL 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 # Source files for UI version
set(SOURCES_UI set(SOURCES_UI
src/main.cpp 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 ${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-mingw-static/lib/libportaudio.a
httplib::httplib httplib::httplib
nlohmann_json::nlohmann_json nlohmann_json::nlohmann_json
imgui::imgui imgui_backends
${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-mingw-static/lib/libglfw3.a ${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-mingw-static/lib/libglfw3.a
glad::glad glad::glad
OpenGL::GL OpenGL::GL
@ -95,7 +125,7 @@ else()
portaudio portaudio
httplib::httplib httplib::httplib
nlohmann_json::nlohmann_json nlohmann_json::nlohmann_json
imgui::imgui imgui_backends
glfw glfw
glad::glad glad::glad
OpenGL::GL OpenGL::GL

51
CMakeLists_noui.txt Normal file
View 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
View 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
View 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
View 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
View 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
View 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

View File

@ -201,6 +201,9 @@ void Pipeline::processingThread() {
} }
void Pipeline::uiThread() { void Pipeline::uiThread() {
// CRITICAL: Make OpenGL context current in THIS thread (not the thread that created it)
ui_->makeContextCurrent();
while (running_ && !ui_->shouldClose()) { while (running_ && !ui_->shouldClose()) {
ui_->setRecordingDuration(recording_duration_); ui_->setRecordingDuration(recording_duration_);
ui_->setProcessingStatus("Processing..."); ui_->setProcessingStatus("Processing...");

View 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>

View 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
View 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
View 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
View 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
View 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
View 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
View 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;
}

View 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;
}

View File

@ -5,6 +5,7 @@
#include <imgui_impl_glfw.h> #include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h> #include <imgui_impl_opengl3.h>
#include <iostream> #include <iostream>
#include <thread>
namespace secondvoice { namespace secondvoice {
@ -39,11 +40,10 @@ bool TranslationUI::initialize() {
// FORCE high-performance GPU (NVIDIA/AMD dedicated) // FORCE high-performance GPU (NVIDIA/AMD dedicated)
std::cout << "[UI] Requesting high-performance GPU..." << std::endl; std::cout << "[UI] Requesting high-performance GPU..." << std::endl;
// OpenGL 4.6 Core Profile to match NVIDIA driver // OpenGL 3.3 - core profile
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create window // Create window
std::cout << "[UI] Creating GLFW window (" << width_ << "x" << height_ << ")..." << std::endl; std::cout << "[UI] Creating GLFW window (" << width_ << "x" << height_ << ")..." << std::endl;
@ -89,12 +89,65 @@ bool TranslationUI::initialize() {
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(window_, true); 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; 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() { void TranslationUI::render() {
glfwPollEvents(); glfwPollEvents();

View File

@ -18,6 +18,7 @@ public:
~TranslationUI(); ~TranslationUI();
bool initialize(); bool initialize();
void makeContextCurrent(); // Make OpenGL context current in calling thread
void render(); void render();
bool shouldClose() const; bool shouldClose() const;

59
test_opengl.cpp Normal file
View 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;
}

View File

@ -5,10 +5,6 @@
"portaudio", "portaudio",
"cpp-httplib", "cpp-httplib",
"nlohmann-json", "nlohmann-json",
{
"name": "imgui",
"features": ["glfw-binding", "opengl3-binding"]
},
"glfw3", "glfw3",
"glad", "glad",
"opengl" "opengl"