528 lines
22 KiB
C
528 lines
22 KiB
C
#include "raylib/raylib.h"
|
|
#include <math.h>
|
|
#define RAYGUI_IMPLEMENTATION
|
|
#include "raylib/raygui.h"
|
|
#if defined(PLATFORM_WEB)
|
|
#include <emscripten/emscripten.h>
|
|
#endif
|
|
|
|
#define UI_WIDTH 450
|
|
#define COLOR_BG (Color){ 25, 25, 30, 255 }
|
|
#define COLOR_PANEL (Color){ 40, 40, 45, 255 }
|
|
#define COLOR_ACCENT (Color){ 0, 120, 240, 255 }
|
|
#define COLOR_TEXT_DIM (Color){ 180, 180, 190, 255 }
|
|
#define COLOR_TEXT_SEC (Color){ 160, 160, 170, 255 }
|
|
|
|
#define MAX_WAVELENGTHS 10
|
|
|
|
typedef struct {
|
|
float d1;
|
|
float d2;
|
|
float lambdas[MAX_WAVELENGTHS];
|
|
int lambdasCount;
|
|
int selectedLambdaIndex;
|
|
float angleM1;
|
|
float angleM1_Y;
|
|
Vector2 center;
|
|
bool gaz;
|
|
float nGaz;
|
|
} Michelson;
|
|
|
|
Color WavelengthToColor(float lambda) {
|
|
float r = 0.0f, g = 0.0f, b = 0.0f;
|
|
if (lambda >= 380 && lambda < 440) { r = -(lambda - 440) / (440 - 380); b = 1.0f; }
|
|
else if (lambda >= 440 && lambda < 490) { g = (lambda - 440) / (490 - 440); b = 1.0f; }
|
|
else if (lambda >= 490 && lambda < 510) { g = 1.0f; b = -(lambda - 510) / (510 - 490); }
|
|
else if (lambda >= 510 && lambda < 580) { r = (lambda - 510) / (580 - 510); g = 1.0f; }
|
|
else if (lambda >= 580 && lambda < 645) { r = 1.0f; g = -(lambda - 645) / (645 - 580); }
|
|
else if (lambda >= 645 && lambda <= 780) { r = 1.0f; }
|
|
|
|
float factor = 1.0f;
|
|
if (lambda >= 380 && lambda < 420) factor = 0.3f + 0.7f * (lambda - 380) / (420 - 380);
|
|
else if (lambda >= 380 && lambda <= 645) factor = 1.0f;
|
|
else if (lambda > 700 && lambda <= 780) factor = 0.3f + 0.7f * (780 - lambda) / (780 - 700);
|
|
|
|
return (Color){(unsigned char)(r * factor * 255), (unsigned char)(g * factor * 255), (unsigned char)(b * factor * 255), 255};
|
|
}
|
|
|
|
void DrawLaserBeam(Vector2 start, Vector2 end, Color color, float thickness) {
|
|
DrawLineEx(start, end, thickness * 4.0f, Fade(color, 0.15f));
|
|
DrawLineEx(start, end, thickness * 2.0f, Fade(color, 0.4f));
|
|
DrawLineEx(start, end, thickness, color);
|
|
}
|
|
|
|
bool GuiButtonRepeat(Rectangle bounds, const char* text, bool shouldRepeat) {
|
|
bool clicked = GuiButton(bounds, text);
|
|
bool held = CheckCollisionPointRec(GetMousePosition(), bounds) && IsMouseButtonDown(MOUSE_LEFT_BUTTON) && shouldRepeat;
|
|
return clicked || held;
|
|
}
|
|
|
|
void DrawInterferenceViewGPU(Michelson *mic, Rectangle rec, Shader shader, bool *isFullscreen) {
|
|
|
|
DrawRectangleRec((Rectangle){rec.x - 4, rec.y - 30, rec.width + 8, rec.height + 34}, COLOR_PANEL);
|
|
DrawText("ECRAN", rec.x, rec.y - 26, 20, COLOR_TEXT_DIM);
|
|
|
|
const char* btnText = *isFullscreen ? "PETIT" : "GRAND";
|
|
if (GuiButton((Rectangle){rec.x + rec.width - 80, rec.y - 28, 80, 24}, btnText)) {
|
|
*isFullscreen = !(*isFullscreen);
|
|
}
|
|
if (CheckCollisionPointRec(GetMousePosition(), (Rectangle){rec.x + rec.width - 80, rec.y - 28, 80, 24})) {
|
|
DrawText("(Touche F)", rec.x + rec.width - 160, rec.y - 22, 10, GRAY);
|
|
}
|
|
|
|
// Shader glsl
|
|
float centerX = rec.x + rec.width / 2.0f;
|
|
float centerY = rec.y + rec.height / 2.0f;
|
|
float center[2] = { centerX, centerY };
|
|
float scrHeight = (float)GetScreenHeight();
|
|
float zoom = *isFullscreen ? 0.7 : 1;
|
|
|
|
float addedOpticalPathOneWay = 0.0f;
|
|
if (mic->gaz) {
|
|
addedOpticalPathOneWay = 100.0f * (mic->nGaz - 1.0f);
|
|
}
|
|
float d2_effective = mic->d2 + addedOpticalPathOneWay;
|
|
|
|
SetShaderValue(shader, GetShaderLocation(shader, "center"), center, SHADER_UNIFORM_VEC2);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "screenHeight"), &scrHeight, SHADER_UNIFORM_FLOAT);
|
|
|
|
SetShaderValue(shader, GetShaderLocation(shader, "d1"), &mic->d1, SHADER_UNIFORM_FLOAT);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "d2"), &d2_effective, SHADER_UNIFORM_FLOAT);
|
|
|
|
float lambdasData[MAX_WAVELENGTHS];
|
|
for(int i = 0; i < MAX_WAVELENGTHS; i++) {
|
|
if (i < mic->lambdasCount) lambdasData[i] = mic->lambdas[i];
|
|
else lambdasData[i] = 0.0f;
|
|
}
|
|
int locLambdas = GetShaderLocation(shader, "lambdas");
|
|
int locCount = GetShaderLocation(shader, "lambdasCount");
|
|
SetShaderValueV(shader, locLambdas, lambdasData, SHADER_UNIFORM_FLOAT, MAX_WAVELENGTHS);
|
|
SetShaderValue(shader, locCount, &mic->lambdasCount, SHADER_UNIFORM_INT);
|
|
|
|
//SetShaderValue(shader, GetShaderLocation(shader, "lambda"), &mic->lambda, SHADER_UNIFORM_FLOAT);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "angleM1"), &mic->angleM1, SHADER_UNIFORM_FLOAT);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "angleM1_Y"), &mic->angleM1_Y, SHADER_UNIFORM_FLOAT);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "zoom"), &zoom, SHADER_UNIFORM_FLOAT);
|
|
|
|
// GPU
|
|
BeginShaderMode(shader);
|
|
DrawRectangleRec(rec, WHITE);
|
|
EndShaderMode();
|
|
|
|
DrawRectangleLinesEx(rec, 1, Fade(COLOR_ACCENT, 0.3f));
|
|
DrawRectangleLinesEx(rec, 2, COLOR_PANEL);
|
|
|
|
int cx = rec.x + rec.width / 2;
|
|
int cy = rec.y + rec.height / 2;
|
|
DrawLine(cx - 10, cy, cx + 10, cy, Fade(WHITE, 0.5f));
|
|
DrawLine(cx, cy - 10, cx, cy + 10, Fade(WHITE, 0.5f));
|
|
}
|
|
|
|
void DrawMichelsonSchema (Michelson *mic) {
|
|
Vector2 c = mic->center;
|
|
//Color laserColor = WavelengthToColor(mic->lambda);
|
|
|
|
float thickness = 3.0f;
|
|
float sourceLen = 450.0f;
|
|
float screenLen = 450.0f;
|
|
float mirrorSize = 140.0f;
|
|
|
|
Vector2 startSource = {c.x - sourceLen, c.y};
|
|
Vector2 posM2 = {c.x + mic->d2, c.y};
|
|
Vector2 posM1 = {c.x, c.y - mic->d1};
|
|
Vector2 endPointM2 = {c.x, c.y + screenLen};
|
|
|
|
float angleRad = -(mic->angleM1 * 2.0f) * (PI / 180.0f);
|
|
float yScreen = c.y + screenLen;
|
|
float vertDist = yScreen - posM1.y;
|
|
float xOff = vertDist * tanf(angleRad);
|
|
Vector2 endPointRetour = { posM1.x + xOff, yScreen };
|
|
|
|
// Laser
|
|
BeginBlendMode(BLEND_ADDITIVE);
|
|
/*
|
|
// Source
|
|
DrawLaserBeam(startSource, c, laserColor, thickness);
|
|
|
|
// Miroir M2 (fixe)
|
|
Vector2 posM2 = {c.x + mic->d2, c.y};
|
|
DrawLaserBeam(c, posM2, laserColor, thickness);
|
|
|
|
// Miroir M1 (mobile)
|
|
Vector2 posM1 = {c.x, c.y - mic->d1};
|
|
DrawLaserBeam(c, posM1, laserColor, thickness);
|
|
|
|
// Projection rayon sur écran (corection tangente)
|
|
float angleRad = -(mic->angleM1 * 2.0f) * (PI / 180.0f);
|
|
float yScreen = c.y + screenLen;
|
|
float vertDist = yScreen - posM1.y;
|
|
float xOff = vertDist * tanf(angleRad);
|
|
Vector2 endPointRetour = { posM1.x + xOff, yScreen };
|
|
DrawLaserBeam(posM1, endPointRetour, Fade(laserColor, 0.6f), thickness);
|
|
|
|
Vector2 endPointM2 = {c.x, c.y + screenLen};
|
|
DrawLaserBeam(c, endPointM2, Fade(laserColor, 0.5f), thickness);
|
|
*/
|
|
float alphaFactor = 1.0f / (float)(mic->lambdasCount > 0 ? mic->lambdasCount : 1);
|
|
if(alphaFactor < 0.3f) alphaFactor = 0.3f; // Min de visibilité
|
|
|
|
for(int i=0; i<mic->lambdasCount; i++) {
|
|
Color laserColor = WavelengthToColor(mic->lambdas[i]);
|
|
laserColor = Fade(laserColor, alphaFactor);
|
|
// Source -> Centre
|
|
DrawLaserBeam(startSource, c, laserColor, thickness);
|
|
// Centre -> Miroir M2 (fixe)
|
|
DrawLaserBeam(c, posM2, laserColor, thickness);
|
|
// Centre -> Miroir M1 (mobile)
|
|
DrawLaserBeam(c, posM1, laserColor, thickness);
|
|
// Retour M1 -> Ecran
|
|
DrawLaserBeam(posM1, endPointRetour, Fade(laserColor, 0.6f), thickness);
|
|
// Retour M2 -> Ecran
|
|
DrawLaserBeam(c, endPointM2, Fade(laserColor, 0.5f), thickness);
|
|
}
|
|
EndBlendMode();
|
|
|
|
// Source
|
|
DrawRectangle(startSource.x - 30, startSource.y - 20, 30, 40, DARKGRAY);
|
|
DrawRectangleLines(startSource.x - 30, startSource.y - 20, 30, 40, GRAY);
|
|
DrawText("Source", startSource.x - 50, startSource.y - 50, 20, LIGHTGRAY);
|
|
|
|
if (mic->gaz) {
|
|
float cellDist = 80.0f;
|
|
float cellW = 60.0f;
|
|
float cellH = 40.0f;
|
|
Rectangle cellRect = {c.x + cellDist, c.y - cellH / 2, cellW, cellH};
|
|
|
|
DrawRectangleRec(cellRect, Fade(BLUE, 0.15f + (mic->nGaz - 1.0f) * 2.0f));
|
|
DrawRectangleLinesEx(cellRect, 2, SKYBLUE);
|
|
|
|
DrawText(TextFormat("n=%.3f", mic->nGaz), c.x + cellDist, c.y + 25, 10, SKYBLUE);
|
|
}
|
|
|
|
// M2
|
|
DrawRectangle(posM2.x, posM2.y - (mirrorSize / 2), 12, mirrorSize, LIGHTGRAY);
|
|
DrawRectangle(posM2.x, posM2.y - (mirrorSize / 2) + 2, 4, mirrorSize - 4, WHITE);
|
|
DrawText("M2", posM2.x + 20, posM2.y - 10, 20, GRAY);
|
|
|
|
// M1
|
|
Rectangle recM1 = {posM1.x, posM1.y, mirrorSize, 12.0f};
|
|
Vector2 originM1 = {mirrorSize / 2, 6.0f};
|
|
DrawRectanglePro(recM1, originM1, mic->angleM1, LIGHTGRAY);
|
|
Rectangle recM1Face = {posM1.x, posM1.y, mirrorSize - 4, 4.0f};
|
|
Vector2 originM1Face = {(mirrorSize - 4) / 2, 6.0f};
|
|
DrawRectanglePro(recM1Face, originM1Face, mic->angleM1, WHITE);
|
|
DrawText("M1", posM1.x - 40, posM1.y - 30, 20, ORANGE);
|
|
|
|
// Séparatrice
|
|
float sepLen = 220.0f;
|
|
Rectangle sepRec = {c.x, c.y, 6.0f, sepLen};
|
|
Vector2 sepOrigin = {2.0f, sepLen / 2};
|
|
DrawRectanglePro(sepRec, sepOrigin, -45.0f, Fade(SKYBLUE, 0.4f));
|
|
DrawRectanglePro((Rectangle){c.x, c.y, 2.0f, sepLen}, (Vector2){1.0f, sepLen / 2}, -45.0f, Fade(WHITE, 0.4f));
|
|
|
|
DrawRectangle(c.x - 300, yScreen, 600, 15, COLOR_PANEL);
|
|
DrawText("Ecran", c.x - 20, yScreen + 20, 20, COLOR_TEXT_DIM);
|
|
}
|
|
|
|
void DrawControlPanel(Michelson *mic) {
|
|
DrawRectangle(0, 0, UI_WIDTH, GetScreenHeight(), Fade(COLOR_PANEL, 0.95f));
|
|
DrawLine(UI_WIDTH, 0, UI_WIDTH, GetScreenHeight(), Fade(WHITE, 0.1f));
|
|
|
|
static int holdTimer = 0;
|
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) holdTimer++;
|
|
else holdTimer = 0;
|
|
bool shouldRepeat = (holdTimer > 30 && (holdTimer % 3 == 0)); // Répète / 3 frames
|
|
|
|
int startX = 20;
|
|
int startY = 30;
|
|
int contentWidth = UI_WIDTH - 40;
|
|
int btnSize = 30;
|
|
int spectrumWidth = contentWidth - (btnSize * 2) - 10;
|
|
int sliderWidth = spectrumWidth;
|
|
|
|
GuiSetStyle(DEFAULT, TEXT_SIZE, 16);
|
|
GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0x2D2D2DFF);
|
|
GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0x454545FF);
|
|
GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x1A1A1AFF);
|
|
GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0xFFFFFFFF);
|
|
GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x505050FF);
|
|
GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x0078D7FF);
|
|
GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0x1E1E1EFF);
|
|
|
|
DrawText("PARAMETRES", startX, startY, 30, WHITE);
|
|
DrawLine(startX, startY + 35, startX + contentWidth, startY + 35, COLOR_ACCENT);
|
|
|
|
bool speedMode = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
|
|
|
|
const char* modeTxtStatus = speedMode ? "(SHIFT ACTIF: VITESSE RAPIDE)" : "(Maintenir SHIFT pour accelerer)";
|
|
Color statusColor = speedMode ? ORANGE : GRAY;
|
|
DrawText(modeTxtStatus, startX, startY + 45, 10, statusColor);
|
|
|
|
// Longueur d'onde
|
|
startY += 80;
|
|
DrawText("SPECTRE (Clic Droit: +/-)", startX, startY, 20, COLOR_TEXT_SEC);
|
|
|
|
int spectrumHeight = 35;
|
|
Rectangle spectrumRect = {startX, startY + 25, contentWidth, spectrumHeight};
|
|
|
|
// spectre
|
|
for (int i = 0; i < spectrumRect.width; i++) {
|
|
float prog = (float)i / spectrumRect.width;
|
|
float l = 380.0f + prog * (780.0f - 380.0f);
|
|
DrawLine(spectrumRect.x + i, spectrumRect.y, spectrumRect.x + i, spectrumRect.y + spectrumRect.height, WavelengthToColor(l));
|
|
}
|
|
DrawRectangleLinesEx(spectrumRect, 1, GRAY);
|
|
|
|
Vector2 mousePos = GetMousePosition();
|
|
float stepLambda = speedMode ? 0.7f : 0.03f;
|
|
|
|
if (CheckCollisionPointRec(mousePos, spectrumRect)) {
|
|
float mouseRatio = (mousePos.x - spectrumRect.x) / spectrumRect.width;
|
|
float mouseLambda = 380.0f + mouseRatio * (780.0f - 380.0f);
|
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) {
|
|
if (mic->selectedLambdaIndex >= 0 && mic->selectedLambdaIndex < mic->lambdasCount) {
|
|
mic->lambdas[mic->selectedLambdaIndex] = mouseLambda;
|
|
}
|
|
}
|
|
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) {
|
|
int foundIdx = -1;
|
|
for(int i = 0; i < mic->lambdasCount; i++) {
|
|
if (fabs(mic->lambdas[i] - mouseLambda) < 15.0f) {
|
|
foundIdx = i; break;
|
|
}
|
|
}
|
|
if (foundIdx != -1) {
|
|
if (mic->lambdasCount > 1) {
|
|
for(int k=foundIdx; k < mic->lambdasCount - 1; k++) {
|
|
mic->lambdas[k] = mic->lambdas[k+1];
|
|
}
|
|
mic->lambdasCount--;
|
|
mic->selectedLambdaIndex = 0;
|
|
}
|
|
} else {
|
|
if (mic->lambdasCount < MAX_WAVELENGTHS) {
|
|
mic->lambdas[mic->lambdasCount] = mouseLambda;
|
|
mic->selectedLambdaIndex = mic->lambdasCount;
|
|
mic->lambdasCount++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//curseur
|
|
for (int i = 0; i < mic->lambdasCount; i++) {
|
|
if (mic->lambdas[i] < 380) mic->lambdas[i] = 380;
|
|
if (mic->lambdas[i] > 780) mic->lambdas[i] = 780;
|
|
|
|
float ratio = (mic->lambdas[i] - 380.0f) / (780.0f - 380.0f);
|
|
float lineX = spectrumRect.x + ratio * spectrumRect.width;
|
|
bool isSel = (i == mic->selectedLambdaIndex);
|
|
|
|
Color lineCol = isSel ? WHITE : GRAY;
|
|
float thick = isSel ? 3.0f : 2.0f;
|
|
|
|
DrawLineEx((Vector2){lineX, spectrumRect.y}, (Vector2){lineX, spectrumRect.y + spectrumRect.height}, thick, lineCol);
|
|
|
|
if(isSel) DrawTriangle((Vector2){lineX-5, spectrumRect.y-6}, (Vector2){lineX+5, spectrumRect.y-6}, (Vector2){lineX, spectrumRect.y}, WHITE);
|
|
}
|
|
|
|
// selction labmda
|
|
startY += spectrumHeight + 35;
|
|
|
|
if (mic->selectedLambdaIndex >= mic->lambdasCount)
|
|
mic->selectedLambdaIndex = 0;
|
|
|
|
float* currentVal = &mic->lambdas[mic->selectedLambdaIndex];
|
|
|
|
if (GuiButtonRepeat((Rectangle){startX, startY, 40, 30}, "-", shouldRepeat))
|
|
*currentVal -= stepLambda;
|
|
|
|
DrawRectangle(startX + 45, startY, contentWidth - 90, 30, COLOR_PANEL);
|
|
DrawRectangleLines(startX + 45, startY, contentWidth - 90, 30, GRAY);
|
|
|
|
Color activeCol = WavelengthToColor(*currentVal);
|
|
DrawRectangle(startX + 50, startY + 5, 20, 20, activeCol);
|
|
DrawText(TextFormat("%.1f nm", *currentVal), startX + 80, startY + 5, 20, WHITE);
|
|
|
|
if (GuiButtonRepeat((Rectangle){startX + contentWidth - 40, startY, 40, 30}, "+", shouldRepeat))
|
|
*currentVal += stepLambda;
|
|
|
|
// lambda acrifs
|
|
startY += 45;
|
|
DrawText("Longueurs d'onde actives :", startX, startY, 20, GRAY);
|
|
startY += 25;
|
|
|
|
int cols = 5;
|
|
int btnW = (contentWidth - (cols - 1) * 5) / cols;
|
|
int btnH = 30;
|
|
|
|
for(int i = 0; i < mic->lambdasCount; i++) {
|
|
int r = i / cols;
|
|
int c = i % cols;
|
|
Rectangle rectBtn = {startX + c * (btnW + 5), startY + r * (btnH + 5), btnW, btnH};
|
|
|
|
bool isSel = (i == mic->selectedLambdaIndex);
|
|
Color cVal = WavelengthToColor(mic->lambdas[i]);
|
|
|
|
if (GuiButton(rectBtn, TextFormat("%.0f", mic->lambdas[i])))
|
|
mic->selectedLambdaIndex = i;
|
|
|
|
if (isSel)
|
|
DrawRectangleLinesEx(rectBtn, 2, WHITE);
|
|
DrawRectangle(rectBtn.x + 2, rectBtn.y + 2, 5, rectBtn.height - 4, cVal);
|
|
}
|
|
|
|
int rows = (mic->lambdasCount + cols - 1) / cols;
|
|
startY += (rows * (btnH + 5)) + 20;
|
|
|
|
|
|
// Pos M1
|
|
startY += 0;
|
|
DrawText(TextFormat("Position M1 : %.2f um", mic->d1), startX, startY, 20, ORANGE);
|
|
|
|
// Pas des + et -
|
|
float stepD1 = speedMode ? 0.05f : 0.006f;
|
|
|
|
if (GuiButtonRepeat((Rectangle){startX, startY + 30, btnSize, 25}, "-", shouldRepeat)) mic->d1 -= stepD1;
|
|
GuiSlider((Rectangle){startX + btnSize + 5, startY + 30, sliderWidth - 75, 25}, NULL, NULL, &mic->d1, 100, 600);
|
|
if (GuiButtonRepeat((Rectangle){startX + btnSize + sliderWidth - 65, startY + 30, btnSize, 25}, "+", shouldRepeat)) mic->d1 += stepD1;
|
|
if (GuiButton((Rectangle){startX + contentWidth - 60, startY + 30, 60, 25}, "Egal")) mic->d1 = mic->d2;
|
|
|
|
|
|
// Angle M1 X
|
|
startY += 90;
|
|
DrawText(TextFormat("Inclinaison M1: %.3f deg", mic->angleM1), startX, startY, 20, ORANGE);
|
|
float stepAngle = speedMode ? 0.05f : 0.0006f;
|
|
if (GuiButtonRepeat((Rectangle){startX, startY + 30, btnSize, 25}, "-", shouldRepeat)) mic->angleM1 -= stepAngle;
|
|
GuiSlider((Rectangle){startX + btnSize + 5, startY + 30, sliderWidth - 75, 25}, 0, 0, &mic->angleM1, -1.0f, 1.0f);
|
|
if (GuiButtonRepeat((Rectangle){startX + btnSize + sliderWidth - 65, startY + 30, btnSize, 25}, "+", shouldRepeat)) mic->angleM1 += stepAngle;
|
|
if (GuiButton((Rectangle){startX + contentWidth - 60, startY + 30, 60, 25}, "Zero")) mic->angleM1 = 0.0f;
|
|
|
|
// Angles M1 Y
|
|
startY += 90;
|
|
stepAngle = speedMode ? 0.05f : 0.0006f;
|
|
DrawText(TextFormat("Inclinaison Y: %.3f deg", mic->angleM1_Y), startX, startY, 20, ORANGE);
|
|
if (GuiButtonRepeat((Rectangle){startX, startY + 30, btnSize, 25}, "-", shouldRepeat)) mic->angleM1_Y -= stepAngle;
|
|
GuiSlider((Rectangle){startX + btnSize + 5, startY + 30, sliderWidth - 75, 25}, 0, 0, &mic->angleM1_Y, -1.0f, 1.0f);
|
|
if (GuiButtonRepeat((Rectangle){startX + btnSize + sliderWidth - 65, startY + 30, btnSize, 25}, "+", shouldRepeat)) mic->angleM1_Y += stepAngle;
|
|
if (GuiButton((Rectangle){startX + contentWidth - 60, startY + 30, 60, 25}, "Zero")) mic->angleM1_Y = 0.0f;
|
|
|
|
// Status
|
|
startY += 70;
|
|
bool isLameAir = (fabs(mic->angleM1) < 0.001f);
|
|
const char* modeTxt = isLameAir ? "LAME D'AIR" : "COIN D'AIR";
|
|
Color modeColor = isLameAir ? SKYBLUE : GREEN;
|
|
|
|
DrawRectangle(startX, startY, contentWidth, 30, Fade(modeColor, 0.2f));
|
|
DrawRectangleLines(startX, startY, contentWidth, 30, modeColor);
|
|
DrawText(modeTxt, startX + 10, startY + 8, 20, modeColor);
|
|
|
|
// Cuve de gaz
|
|
startY += 50;
|
|
DrawLine(startX, startY - 10, startX + contentWidth, startY - 10, Fade(GRAY, 0.3f));
|
|
DrawText("Cuve de Gaz (Indice n)", startX, startY, 20, SKYBLUE);
|
|
GuiCheckBox((Rectangle){startX, startY + 30, 20, 20}, "Cuve", &mic->gaz);
|
|
if (mic->gaz) {
|
|
DrawText(TextFormat("n = %.4f", mic->nGaz), startX + 150, startY + 30, 20, WHITE);
|
|
float stepN = speedMode ? 0.001f : 0.00005f;
|
|
if (GuiButtonRepeat((Rectangle){startX, startY + 55, btnSize, 25}, "-", shouldRepeat)) mic->nGaz -= stepN;
|
|
GuiSlider((Rectangle){startX + btnSize + 5, startY + 55, sliderWidth - 10, 25}, NULL, NULL, &mic->nGaz, 1.000f, 1.100f);
|
|
if (GuiButtonRepeat((Rectangle){startX + btnSize + sliderWidth, startY + 55, btnSize, 25}, "+", shouldRepeat)) mic->nGaz += stepN;
|
|
if (mic->nGaz < 1.0f) mic->nGaz = 1.0f;
|
|
//startY += 90;
|
|
}
|
|
|
|
// Données
|
|
startY += 100;
|
|
DrawLine(startX, startY - 10, startX + contentWidth, startY - 10, GRAY);
|
|
DrawText("DONNEES TEMPS REEL", startX, startY, 20, GRAY);
|
|
|
|
float delta = 2 * (mic->d1 - mic->d2);
|
|
DrawText(TextFormat("Delta = %.2f um", delta), startX, startY + 35, 20, WHITE);
|
|
|
|
float refLambda = mic->lambdas[mic->selectedLambdaIndex];
|
|
float p = (delta * 1000.0f) / refLambda;
|
|
DrawText(TextFormat("Ordre p (sel) = %.2f", p), startX, startY + 65, 20, WHITE);
|
|
|
|
// Bas
|
|
int bottomY = GetScreenHeight() - 40;
|
|
DrawLine(0, bottomY, UI_WIDTH, bottomY, Fade(WHITE, 0.1f));
|
|
int fps = GetFPS();
|
|
Color fpsColor = (fps >= 100) ? COLOR_ACCENT : (fps >= 60 ? GREEN : (fps >= 30 ? ORANGE : RED));
|
|
DrawText("STATUT:", startX, bottomY + 12, 20, COLOR_TEXT_DIM);
|
|
DrawText(TextFormat("%i FPS", fps), startX + 100, bottomY + 12, 20, fpsColor);
|
|
}
|
|
|
|
Michelson mic = {0};
|
|
Shader shader;
|
|
bool isFullscreen = false;
|
|
Rectangle normalBounds = {0};
|
|
Rectangle fullScreenBounds = {0};
|
|
|
|
void UpdateDrawFrame(void) {
|
|
if (IsKeyPressed(KEY_F)) {
|
|
isFullscreen = !isFullscreen;
|
|
}
|
|
Rectangle currentViewBounds = isFullscreen ? fullScreenBounds : normalBounds;
|
|
BeginDrawing();
|
|
ClearBackground(COLOR_BG);
|
|
float gridThick = 1.1f;
|
|
float gridAlpha = 0.03f;
|
|
// Grille fond
|
|
for(int i = UI_WIDTH; i < 1920; i += 100) DrawLine(i, 0, i, 1080, Fade(WHITE, 0.05f));
|
|
for(int i = 0; i < 1080; i += 100) DrawLine(UI_WIDTH, i, 1920, i, Fade(WHITE, 0.05f));
|
|
for(int i = UI_WIDTH; i < 1920; i += 100) {
|
|
DrawLineEx((Vector2){i, 0}, (Vector2){i, 1080}, gridThick, Fade(WHITE, gridAlpha));
|
|
}
|
|
for(int i = 0; i < 1080; i += 100) {
|
|
DrawLineEx((Vector2){UI_WIDTH, i}, (Vector2){1920, i}, gridThick, Fade(WHITE, gridAlpha));
|
|
}
|
|
|
|
DrawMichelsonSchema(&mic);
|
|
DrawControlPanel(&mic);
|
|
DrawInterferenceViewGPU(&mic, currentViewBounds, shader, &isFullscreen);
|
|
EndDrawing();
|
|
}
|
|
|
|
|
|
int main () {
|
|
//SetConfigFlags(FLAG_MSAA_4X_HINT);
|
|
#if !defined(PLATFORM_WEB)
|
|
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
|
#endif
|
|
|
|
InitWindow(1920, 1080, "Interferometre de Michelson");
|
|
SetTargetFPS(144);
|
|
|
|
#if defined(PLATFORM_WEB)
|
|
shader = LoadShader(0, "glsl/michelson_web.frag");
|
|
#else
|
|
shader = LoadShader(0, "glsl/michelson.frag");
|
|
#endif
|
|
|
|
mic.center = (Vector2){ UI_WIDTH + (1920 - UI_WIDTH) / 2.0f - 100, 1080 / 2.0f };
|
|
mic.d1 = 250.0f;
|
|
mic.d2 = 250.0f;
|
|
mic.lambdas[0] = 550.0f;
|
|
mic.lambdasCount = 1;
|
|
mic.selectedLambdaIndex = 0;
|
|
mic.angleM1 = 0.0f;
|
|
mic.angleM1_Y = 0.0f;
|
|
mic.nGaz = 1.0f;
|
|
mic.gaz = false;
|
|
|
|
normalBounds = (Rectangle){1920 - 530, 50, 500, 500};
|
|
fullScreenBounds = (Rectangle){UI_WIDTH + 10, 40, 1920 - UI_WIDTH - 20, 1030};
|
|
|
|
#if defined(PLATFORM_WEB)
|
|
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
|
#else
|
|
while (!WindowShouldClose()) {
|
|
UpdateDrawFrame();
|
|
}
|
|
#endif
|
|
|
|
CloseWindow();
|
|
return 0;
|
|
}
|