Compare commits
38 Commits
08cac5c6e9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b45c515d4 | |||
| ebd2ba2e51 | |||
| e78af26734 | |||
| 42d69b6ce4 | |||
| 8d42cda17f | |||
| 5010c30886 | |||
| bcdc8b1baa | |||
| 40213d7e69 | |||
| 99fbef5c4b | |||
| a4c62bc3a4 | |||
| a71641b989 | |||
| ea3530c01e | |||
| 7b5cf06bd0 | |||
| 1255038efb | |||
| 60c3754dd6 | |||
| a3d4ad3922 | |||
| fad31cdd2f | |||
| fa9d871479 | |||
| adb6b8b315 | |||
| f779618c7c | |||
| d474c0e670 | |||
| a82295ee6b | |||
| cd8200436b | |||
| 911deefbf5 | |||
| d8e178fe06 | |||
| acbda14a43 | |||
| 88d6ff6532 | |||
| 03b3351b50 | |||
| ba1572b11c | |||
| e476666ff7 | |||
| f94b4628ed | |||
| 71e063c001 | |||
| fddec3f04b | |||
| 1b87a6fb9e | |||
| 200e9a44b7 | |||
| 37b5ce3951 | |||
| 088d5b7739 | |||
| c0465113d0 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/raylib_ignore
|
||||
/web
|
||||
michelson
|
||||
7
Makefile
7
Makefile
@ -3,6 +3,13 @@ michelson: main.c
|
||||
|
||||
clean:
|
||||
rm -f michelson
|
||||
rm -r web
|
||||
|
||||
run:
|
||||
./michelson
|
||||
|
||||
web: main.c
|
||||
mkdir -p web && emcc -o web/index.html main.c -Os -Wall -std=c99 -DPLATFORM_WEB -s USE_GLFW=3 -s ALLOW_MEMORY_GROWTH=1 -I. --shell-file minshell.html --preload-file glsl/michelson_web.frag raylib/libraylib.web.a
|
||||
|
||||
webrun:
|
||||
cd web && python -m http.server 8000 && cd ..
|
||||
|
||||
65
README.md
Normal file
65
README.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Simulateur d'Interféromètre de Michelson
|
||||
|
||||
Une simulation interactive temps réel et physiquement réaliste de l'interféromètre de Michelson. Ce projet permet de visualiser les figures d'interférences (franges et anneaux) en manipulant les composants optiques (miroirs, source lumineuse, milieu).
|
||||
|
||||

|
||||
|
||||
## Fonctionnalités
|
||||
|
||||
### Contrôle et Simulation
|
||||
* **Miroir Mobile (M1) :** Translation et inclinaison sur deux axes.
|
||||
* **Sources Lumineuses :**
|
||||
* Spectre (380nm - 780nm).
|
||||
* Gestion de **sources polychromatiques** (ajout/suppression de longueurs d'onde multiples).
|
||||
* Rendu additif des couleurs.
|
||||
* **Milieux dispersifs :** Ajout d'une cuve de gaz avec indice de réfraction variable n pour visualiser le déphasage.
|
||||
|
||||
### Performance & Rendu
|
||||
* **Rendu GPU :** Calcul des interférences par **shader (GLSL)** pour des performances élevées.
|
||||
* **Interface UI :** `raygui`.
|
||||
* **Optimisation :** Sélecteur de **FPS Cible** (30, 60, 120, 144, Illimité).
|
||||
* **Vues :** Schéma optique 2D + Vue "Écran".
|
||||
|
||||
## Installation et Compilation
|
||||
|
||||
### Prérequis
|
||||
* **[Raylib](https://www.raylib.com/)**
|
||||
* **[Emscripten](https://github.com/emscripten-core/emscripten/)**
|
||||
|
||||
### Compilation (Linux / Mac)
|
||||
|
||||
```bash
|
||||
make
|
||||
make run
|
||||
```
|
||||
ou
|
||||
```bash
|
||||
gcc main.c -o michelson -lraylib -lGL -lm -lpthread -ldl -lrt -lX11
|
||||
./michelson
|
||||
```
|
||||
|
||||
### Version Web (Emscripten)
|
||||
|
||||
```bash
|
||||
make web
|
||||
make webrun
|
||||
```
|
||||
ou
|
||||
```bash
|
||||
mkdir -p web && emcc -o web/index.html main.c -Os -Wall -std=c99 -DPLATFORM_WEB -s USE_GLFW=3 -s ALLOW_MEMORY_GROWTH=1 -I. --shell-file minshell.html --preload-file glsl/michelson_web.frag raylib/libraylib.web.a
|
||||
```
|
||||
|
||||
## Contrôles Utilisateur
|
||||
|
||||
| Action | Commande |
|
||||
| --- | --- |
|
||||
| **Plein Écran** | Touche `F` |
|
||||
| **Sélectionner une longueur d'onde** | `Clic Gauche` sur le spectre |
|
||||
| **Ajouter une longueur d'onde** | `Clic Droit` sur une zone vide du spectre |
|
||||
| **Supprimer une longueur d'onde** | `Clic Droit` sur une ligne existante |
|
||||
| **Régler les miroirs** | Sliders / boutons `+` / `-` |
|
||||
| **Précision / Vitesse** | Maintenir `Shift` |
|
||||
|
||||
## Physique du projet
|
||||
|
||||
Calcule de l'intensité lumineuse en tout point de l'écran en se basant sur la différence de marche.
|
||||
85
glsl/michelson.frag
Normal file
85
glsl/michelson.frag
Normal file
@ -0,0 +1,85 @@
|
||||
#version 330
|
||||
|
||||
// Entrées (de Raylib)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
uniform vec2 center;
|
||||
uniform float screenHeight;
|
||||
//uniform vec2 resolution;
|
||||
uniform float d1;
|
||||
uniform float d2;
|
||||
//uniform float lambda;
|
||||
uniform float angleM1;
|
||||
uniform float angleM1_Y;
|
||||
uniform float zoom;
|
||||
uniform float lambdas[10];
|
||||
uniform int lambdasCount;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
vec3 WavelengthToRGB(float l) {
|
||||
float r = 0.0; float g = 0.0; float b = 0.0;
|
||||
if (l >= 380.0 && l < 440.0) { r = -(l - 440.0) / (440.0 - 380.0); b = 1.0; }
|
||||
else if (l >= 440.0 && l < 490.0) { g = (l - 440.0) / (490.0 - 440.0); b = 1.0; }
|
||||
else if (l >= 490.0 && l < 510.0) { g = 1.0; b = -(l - 510.0) / (510.0 - 490.0); }
|
||||
else if (l >= 510.0 && l < 580.0) { r = (l - 510.0) / (580.0 - 510.0); g = 1.0; }
|
||||
else if (l >= 580.0 && l < 645.0) { r = 1.0; g = -(l - 645.0) / (645.0 - 580.0); }
|
||||
else if (l >= 645.0 && l <= 780.0) { r = 1.0; }
|
||||
|
||||
float factor = 1.0;
|
||||
if (l >= 380.0 && l < 420.0) factor = 0.3 + 0.7 * (l - 380.0) / (420.0 - 380.0);
|
||||
else if (l >= 380.0 && l <= 645.0) factor = 1.0;
|
||||
else if (l > 700.0 && l <= 780.0) factor = 0.3 + 0.7 * (780.0 - l) / (780.0 - 700.0);
|
||||
|
||||
return vec3(r * factor, g * factor, b * factor);
|
||||
}
|
||||
|
||||
void main() {
|
||||
float pixelX = gl_FragCoord.x;
|
||||
float pixelY = screenHeight - gl_FragCoord.y;
|
||||
|
||||
// Diff de marche du à l'axe (2 * e) + micro -> nano
|
||||
float deltaLnm = 2.0 * (d1 - d2) * 1000.0;
|
||||
|
||||
float relX = (pixelX - center.x) * zoom;
|
||||
float relY = (pixelY - center.y) * zoom;
|
||||
|
||||
// r^2
|
||||
float radiusSq = relX * relX + relY * relY;
|
||||
|
||||
// Diff de marche du au coin d'air
|
||||
float wDelta = (relX * angleM1 + relY * angleM1_Y) * 200.0;
|
||||
|
||||
float cosFactor = 1.0 - (radiusSq * 0.000004);
|
||||
|
||||
float currDelta = (deltaLnm * cosFactor) + wDelta;
|
||||
|
||||
vec3 accumColor = vec3(0.0);
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
if (i >= lambdasCount) break;
|
||||
float l = lambdas[i];
|
||||
if (l < 1.0) l = 550.0;
|
||||
vec3 baseColorVec = WavelengthToRGB(l);
|
||||
float K = PI / l;
|
||||
float phase = currDelta * K;
|
||||
float intensity = cos(phase);
|
||||
intensity = intensity * intensity;
|
||||
accumColor += baseColorVec * intensity;
|
||||
}
|
||||
|
||||
// finalColor = vec4(accumColor, 1.0);
|
||||
|
||||
// float K = PI / lambda;
|
||||
// float phase = currDelta * K;
|
||||
// float intensity = cos(phase);
|
||||
// intensity = intensity * intensity;
|
||||
|
||||
// vec3 finalVec = baseColorVec * intensity;
|
||||
|
||||
//finalColor = vec4(finalVec, 1.0);
|
||||
finalColor = vec4(accumColor, 1.0);
|
||||
}
|
||||
75
glsl/michelson_web.frag
Normal file
75
glsl/michelson_web.frag
Normal file
@ -0,0 +1,75 @@
|
||||
#version 100
|
||||
|
||||
precision highp float;
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
uniform vec2 center;
|
||||
uniform float screenHeight;
|
||||
uniform float d1;
|
||||
uniform float d2;
|
||||
uniform float angleM1;
|
||||
uniform float angleM1_Y;
|
||||
uniform float zoom;
|
||||
|
||||
uniform float lambdas[10];
|
||||
uniform int lambdasCount;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
vec3 WavelengthToRGB(float l) {
|
||||
float r = 0.0; float g = 0.0; float b = 0.0;
|
||||
if (l >= 380.0 && l < 440.0) { r = -(l - 440.0) / (440.0 - 380.0); b = 1.0; }
|
||||
else if (l >= 440.0 && l < 490.0) { g = (l - 440.0) / (490.0 - 440.0); b = 1.0; }
|
||||
else if (l >= 490.0 && l < 510.0) { g = 1.0; b = -(l - 510.0) / (510.0 - 490.0); }
|
||||
else if (l >= 510.0 && l < 580.0) { r = (l - 510.0) / (580.0 - 510.0); g = 1.0; }
|
||||
else if (l >= 580.0 && l < 645.0) { r = 1.0; g = -(l - 645.0) / (645.0 - 580.0); }
|
||||
else if (l >= 645.0 && l <= 780.0) { r = 1.0; }
|
||||
|
||||
float factor = 1.0;
|
||||
if (l >= 380.0 && l < 420.0) factor = 0.3 + 0.7 * (l - 380.0) / (420.0 - 380.0);
|
||||
else if (l >= 380.0 && l <= 645.0) factor = 1.0;
|
||||
else if (l > 700.0 && l <= 780.0) factor = 0.3 + 0.7 * (780.0 - l) / (780.0 - 700.0);
|
||||
|
||||
return vec3(r * factor, g * factor, b * factor);
|
||||
}
|
||||
|
||||
void main() {
|
||||
float pixelX = gl_FragCoord.x;
|
||||
float pixelY = screenHeight - gl_FragCoord.y;
|
||||
|
||||
float deltaLnm = 2.0 * (d1 - d2) * 1000.0;
|
||||
|
||||
float relX = (pixelX - center.x) * zoom;
|
||||
float relY = (pixelY - center.y) * zoom;
|
||||
|
||||
float radiusSq = relX * relX + relY * relY;
|
||||
|
||||
float wDelta = (relX * angleM1 + relY * angleM1_Y) * 200.0;
|
||||
|
||||
float cosFactor = 1.0 - (radiusSq * 0.000004);
|
||||
|
||||
float currDelta = (deltaLnm * cosFactor) + wDelta;
|
||||
|
||||
vec3 accumColor = vec3(0.0);
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
if (i >= lambdasCount) break;
|
||||
|
||||
float l = lambdas[i];
|
||||
if (l < 1.0) l = 550.0;
|
||||
|
||||
vec3 baseColorVec = WavelengthToRGB(l);
|
||||
|
||||
float K = PI / l;
|
||||
float phase = currDelta * K;
|
||||
|
||||
float intensity = cos(phase);
|
||||
intensity = intensity * intensity;
|
||||
|
||||
accumColor += baseColorVec * intensity;
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(accumColor, 1.0);
|
||||
}
|
||||
BIN
img/screenshot.png
Normal file
BIN
img/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 179 KiB |
545
main.c
545
main.c
@ -1,21 +1,32 @@
|
||||
#include "raylib.h"
|
||||
#include "raylib/raylib.h"
|
||||
#include <math.h>
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h"
|
||||
#include "raylib/raygui.h"
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#define UI_WIDTH 400
|
||||
#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 lambda;
|
||||
float lambdas[MAX_WAVELENGTHS];
|
||||
int lambdasCount;
|
||||
int selectedLambdaIndex;
|
||||
float angleM1;
|
||||
float angleM1_Y;
|
||||
Vector2 center;
|
||||
bool gaz;
|
||||
float nGaz;
|
||||
int targetFps;
|
||||
} Michelson;
|
||||
|
||||
Color WavelengthToColor(float lambda) {
|
||||
@ -41,71 +52,98 @@ void DrawLaserBeam(Vector2 start, Vector2 end, Color color, float thickness) {
|
||||
DrawLineEx(start, end, thickness, color);
|
||||
}
|
||||
|
||||
void DrawInterferenceView(Michelson *mic, Rectangle rec) {
|
||||
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 - 30, 20, WHITE);
|
||||
DrawText("ECRAN", rec.x, rec.y - 26, 20, COLOR_TEXT_DIM);
|
||||
|
||||
DrawRectangleRec(rec, BLACK);
|
||||
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 scrHeight = 1080.0f;
|
||||
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));
|
||||
|
||||
Color baseColor = WavelengthToColor(mic->lambda);
|
||||
|
||||
// Diff de marche du à l'axe (2 * e) + micro -> nano
|
||||
float deltaLnm = 2.0f * (mic->d1 - mic->d2) * 1000.0f;
|
||||
DrawRectangleLinesEx(rec, 2, COLOR_PANEL);
|
||||
|
||||
int cx = rec.x + rec.width / 2;
|
||||
int cy = rec.y + rec.height / 2;
|
||||
|
||||
float K = PI / mic->lambda;
|
||||
|
||||
// Dessin pixel par pixel lent... => faire avec gpu
|
||||
for (int y = rec.y; y < rec.y + rec.height; y++) {
|
||||
for (int x = rec.x; x < rec.x + rec.width; x++) {
|
||||
float relX = (float)(x - cx);
|
||||
float relY = (float)(y - cy);
|
||||
float radiusSq = relX * relX + relY * relY;
|
||||
|
||||
//if (radiusSq > (rec.width / 2.0f - 5) * (rec.width / 2.0f - 5)) continue;
|
||||
|
||||
// Diff de marche lamme d'air 2 * e cos(i) mais petits angles => cos(i) ~ 1 - i^2/2 mais i ~ r/f et r^2 = x^2 + y^2
|
||||
float ringFactor = radiusSq * 0.065f;
|
||||
// Diff de marche dut au coin d'air
|
||||
float wDelta = relX * mic->angleM1 * 200.0f;
|
||||
|
||||
float currDelta = deltaLnm - ringFactor + wDelta;
|
||||
|
||||
// Formule de Fresnel : I = I_0 * cos^2(phi)
|
||||
float phase = currDelta * K;
|
||||
float intensity = cosf(phase);
|
||||
intensity = intensity * intensity;
|
||||
|
||||
Color pixColor = {(unsigned char)(baseColor.r * intensity), (unsigned char)(baseColor.g * intensity), (unsigned char)(baseColor.b * intensity), 255 };
|
||||
|
||||
DrawPixel(x, y, pixColor);
|
||||
}
|
||||
}
|
||||
|
||||
DrawRectangleLinesEx(rec, 2, COLOR_PANEL);
|
||||
|
||||
// croix centre
|
||||
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);
|
||||
//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
|
||||
Vector2 startSource = {c.x - sourceLen, c.y};
|
||||
DrawLaserBeam(startSource, c, laserColor, thickness);
|
||||
|
||||
// Miroir M2 (fixe)
|
||||
@ -126,6 +164,24 @@ void DrawMichelsonSchema (Michelson *mic) {
|
||||
|
||||
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
|
||||
@ -133,6 +189,18 @@ void DrawMichelsonSchema (Michelson *mic) {
|
||||
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);
|
||||
@ -162,97 +230,372 @@ 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));
|
||||
|
||||
int startX = 30;
|
||||
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 buttonWidth = 70;
|
||||
int spacing = 20;
|
||||
int contentWidth = UI_WIDTH - 60;
|
||||
int sliderWidth = contentWidth - buttonWidth - spacing - 15;
|
||||
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); // Gris foncé boutons
|
||||
GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0x454545FF); // Gris clair hover
|
||||
GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x1A1A1AFF); // Très foncé click
|
||||
GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0xFFFFFFFF); // Texte blanc
|
||||
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); // Bordures bleues (focus)
|
||||
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);
|
||||
|
||||
// Sliders
|
||||
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 M2 (d1 - d2)
|
||||
startY += 0;
|
||||
float currentDiff = mic->d1 - mic->d2;
|
||||
DrawText(TextFormat("Distance M1 - M2: %.2f um", currentDiff), 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;
|
||||
|
||||
float sliderVal = currentDiff;
|
||||
GuiSlider((Rectangle){startX + btnSize + 5, startY + 30, sliderWidth - 75, 25}, NULL, NULL, &sliderVal, -100.0f, 100.0f);
|
||||
mic->d1 = mic->d2 + sliderVal;
|
||||
|
||||
if (GuiButtonRepeat((Rectangle){startX, startY + 30, btnSize, 25}, "-", shouldRepeat)) mic->d1 -= stepD1;
|
||||
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;
|
||||
DrawText(TextFormat("Longueur d'onde: %.0f nm", mic->lambda), startX, startY, 20, COLOR_TEXT_SEC);
|
||||
GuiSlider((Rectangle){startX, startY + 30, contentWidth - 45, 25}, NULL, NULL, &mic->lambda, 380, 780);
|
||||
DrawRectangle(startX + contentWidth - 35, startY + 30, 35, 25, WavelengthToColor(mic->lambda));
|
||||
|
||||
startY += 90;
|
||||
DrawText(TextFormat("Position M1 (d1): %.1f um", mic->d1), startX, startY, 20, ORANGE);
|
||||
GuiSlider((Rectangle){startX, startY + 30, sliderWidth, 25}, NULL, NULL, &mic->d1, 100, 600);
|
||||
if (GuiButton((Rectangle){startX + sliderWidth + spacing + 15, startY + 30, buttonWidth, 25}, "Egal")) mic->d1 = mic->d2;
|
||||
|
||||
startY += 90;
|
||||
DrawText(TextFormat("Inclinaison M1: %.2f deg", mic->angleM1), startX, startY, 20, ORANGE);
|
||||
GuiSlider((Rectangle){startX, startY + 30, sliderWidth, 25}, "-1", "+1", &mic->angleM1, -1.0f, 1.0f);
|
||||
if (GuiButton((Rectangle){startX + sliderWidth + spacing + 15, startY + 30, buttonWidth, 25}, "0.0")) mic->angleM1 = 0.0f;
|
||||
|
||||
bool isLameAir = (fabs(mic->angleM1) < 0.01f);
|
||||
const char* modeTxt = isLameAir ? "MODE: LAME D'AIR" : "MODE: COIN D'AIR";
|
||||
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 + 70, contentWidth, 30, Fade(modeColor, 0.2f));
|
||||
DrawRectangleLines(startX, startY + 70, contentWidth, 30, modeColor);
|
||||
DrawText(modeTxt, startX + 10, startY + 78, 18, modeColor);
|
||||
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 += 150;
|
||||
DrawLine(startX, startY - 20, startX + contentWidth, startY - 20, GRAY);
|
||||
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 p = (delta * 1000.0f) / mic->lambda;
|
||||
float refLambda = mic->lambdas[mic->selectedLambdaIndex];
|
||||
float p = (delta * 1000.0f) / refLambda;
|
||||
DrawText(TextFormat("Ordre p = %.2f", p), startX, startY + 65, 20, WHITE);
|
||||
|
||||
// FPS
|
||||
int bottomY = GetScreenHeight() - 40;
|
||||
DrawLine(0, bottomY, UI_WIDTH, bottomY, Fade(WHITE, 0.1f));
|
||||
int perfStartY = bottomY - 80;
|
||||
|
||||
DrawLine(startX, perfStartY - 10, startX + contentWidth, perfStartY - 10, GRAY);
|
||||
DrawText("PERFORMANCES (Cible FPS)", startX, perfStartY, 20, GRAY);
|
||||
|
||||
int fpsValues[] = {0, 30, 60, 120, 144};
|
||||
const char* fpsTexts[] = {"MAX", "30", "60", "120", "144"};
|
||||
int fpsCount = 5;
|
||||
int fpsSpacing = 5;
|
||||
int fpsBtnW = (contentWidth - (fpsSpacing * (fpsCount - 1))) / fpsCount;
|
||||
|
||||
for (int i = 0; i < fpsCount; i++) {
|
||||
Rectangle fpsRect = {startX + i * (fpsBtnW + fpsSpacing), perfStartY + 30, fpsBtnW, 25};
|
||||
bool isCurrent = (mic->targetFps == i);
|
||||
if (GuiButton(fpsRect, fpsTexts[i])) {
|
||||
mic->targetFps = i;
|
||||
SetTargetFPS(fpsValues[i]);
|
||||
}
|
||||
if (isCurrent) {
|
||||
DrawRectangleLinesEx(fpsRect, 2, COLOR_ACCENT);
|
||||
DrawRectangle(fpsRect.x + 2, fpsRect.y + 2, fpsRect.width-4, fpsRect.height-4, Fade(COLOR_ACCENT, 0.2f));
|
||||
}
|
||||
}
|
||||
|
||||
// Bas
|
||||
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));
|
||||
|
||||
int currentFpsVal = fpsValues[mic->targetFps];
|
||||
DrawText("STATUT:", startX, bottomY + 12, 20, COLOR_TEXT_DIM);
|
||||
DrawText(TextFormat("%i FPS", fps), startX + 100, bottomY + 12, 20, fpsColor);
|
||||
DrawText(TextFormat("%i FPS (%s)", fps, (currentFpsVal == 0 ? "Max" : TextFormat("%i", currentFpsVal))), startX + 100, bottomY + 12, 20, fpsColor);
|
||||
}
|
||||
|
||||
int main () {
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(1920, 1080, "Interferometre de Michelson");
|
||||
SetTargetFPS(144);
|
||||
Michelson mic = {0};
|
||||
Shader shader;
|
||||
bool isFullscreen = false;
|
||||
Rectangle normalBounds = {0};
|
||||
Rectangle fullScreenBounds = {0};
|
||||
#if !defined(PLATFORM_WEB)
|
||||
RenderTexture2D target;
|
||||
#endif
|
||||
|
||||
Michelson mic = {0};
|
||||
mic.center = (Vector2){ UI_WIDTH + (1920 - UI_WIDTH) / 2.0f - 100, 1080 / 2.0f };
|
||||
mic.d1 = 250.0f;
|
||||
mic.d2 = 250.0f;
|
||||
mic.lambda = 550.0f;
|
||||
mic.angleM1 = 0.0f;
|
||||
void UpdateDrawFrame(void) {
|
||||
if (IsKeyPressed(KEY_F)) {
|
||||
isFullscreen = !isFullscreen;
|
||||
}
|
||||
|
||||
Rectangle screenViewBounds = {1920 - 530, 50, 500, 500};
|
||||
//Rectangle screenViewBounds = {400, 0, 1080, 1080};
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
Rectangle currentViewBounds = isFullscreen ? fullScreenBounds : normalBounds;
|
||||
#if defined(PLATFORM_WEB)
|
||||
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);
|
||||
DrawInterferenceView(&mic, screenViewBounds);
|
||||
DrawInterferenceViewGPU(&mic, currentViewBounds, shader, &isFullscreen);
|
||||
EndDrawing();
|
||||
}
|
||||
#else
|
||||
float scale = fminf((float)GetScreenWidth() / 1920, (float)GetScreenHeight() / 1080);
|
||||
float newWidth = 1920 * scale;
|
||||
float newHeight = 1080 * scale;
|
||||
float offsetX = (GetScreenWidth() - newWidth) * 0.5f;
|
||||
float offsetY = (GetScreenHeight() - newHeight) * 0.5f;
|
||||
SetMouseOffset(-offsetX, -offsetY);
|
||||
SetMouseScale(1.0f / scale, 1.0f / scale);
|
||||
BeginTextureMode(target);
|
||||
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);
|
||||
EndTextureMode();
|
||||
BeginDrawing();
|
||||
ClearBackground(COLOR_BG);
|
||||
Rectangle sourceRec = {0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height};
|
||||
Rectangle destRec = { offsetX, offsetY, newWidth, newHeight };
|
||||
DrawTexturePro(target.texture, sourceRec, destRec, (Vector2){0, 0}, 0.0f, WHITE);
|
||||
EndDrawing();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main () {
|
||||
#if defined(PLATFORM_WEB)
|
||||
InitWindow(1920, 1080, "Interferometre de Michelson");
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
#else
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_MSAA_4X_HINT);
|
||||
InitWindow(1280, 720, "Interferometre de Michelson");
|
||||
#endif
|
||||
|
||||
SetTargetFPS(0);
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
shader = LoadShader(0, "glsl/michelson_web.frag");
|
||||
#else
|
||||
shader = LoadShader(0, "glsl/michelson.frag");
|
||||
#endif
|
||||
|
||||
#if !defined(PLATFORM_WEB)
|
||||
target = LoadRenderTexture(1920, 1080);
|
||||
SetTextureFilter(target.texture, TEXTURE_FILTER_BILINEAR);
|
||||
#endif
|
||||
|
||||
mic.center = (Vector2){ UI_WIDTH + (1920 - UI_WIDTH) / 2.0f - 100, 1080 / 2.0f };
|
||||
mic.d1 = 265.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;
|
||||
}
|
||||
|
||||
58
minshell.html
Normal file
58
minshell.html
Normal file
@ -0,0 +1,58 @@
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Interferometre Michelson - Web</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #19191e;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
canvas.emscripten {
|
||||
border: 0px none;
|
||||
background-color: #19191e;
|
||||
display: block;
|
||||
|
||||
aspect-ratio: 16 / 9;
|
||||
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
|
||||
height: auto;
|
||||
width: auto;
|
||||
|
||||
box-shadow: 0 0 20px rgba(0,0,0,0.5);
|
||||
|
||||
image-rendering: -moz-crisp-edges;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
|
||||
<script type='text/javascript'>
|
||||
var Module = {
|
||||
print: (function() {
|
||||
return function(text) { console.log(text); };
|
||||
})(),
|
||||
printErr: function(text) { console.error(text); },
|
||||
canvas: (function() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
return canvas;
|
||||
})()
|
||||
};
|
||||
</script>
|
||||
{{{ SCRIPT }}}
|
||||
</body>
|
||||
</html>
|
||||
BIN
raylib/libraylib.web.a
Normal file
BIN
raylib/libraylib.web.a
Normal file
Binary file not shown.
1727
raylib/raylib.h
Normal file
1727
raylib/raylib.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user