Created
July 17, 2025 15:06
-
-
Save MurageKibicho/250444a28cc81ab67182cd5279014cdd to your computer and use it in GitHub Desktop.
Texture camera second step
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef __EMSCRIPTEN__ | |
#include <emscripten.h> | |
#include <SDL.h> | |
#include <SDL_opengles2.h> | |
#else | |
#include <SLD2/SDL.h> | |
#include <SDL2/SDL_opengles2.h> | |
#endif | |
#ifndef M_PI | |
#define M_PI 3.14159265358979323846 | |
#endif | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
#include <math.h> | |
#include "SDL2_gfxPrimitives.h" | |
//Compile:emcc TextureCamera.c SDL2_gfxPrimitives.c -s USE_SDL=2 -s FULL_ES2=1 -s --preload-file muragekibicho.bmp WASM=1 -o TextureCamera.html | |
//Preview:emrun TextureCamera.html | |
typedef struct scene_struct *Scene; | |
struct scene_struct | |
{ | |
SDL_Renderer *renderer; | |
SDL_Window *window; | |
SDL_Texture *texture; | |
Uint32 windowID; | |
int windowWidth; | |
int windowHeight; | |
}; | |
typedef struct thin_lens_struct *ThinLens; | |
struct thin_lens_struct | |
{ | |
int lensHeight; | |
int xCenter; | |
int yCenter; | |
float objectFocalPoint; | |
float imageFocalPoint; | |
}; | |
ThinLens CreateThinLens(int lensHeight, int xCenter, int yCenter) | |
{ | |
ThinLens thinLens = malloc(sizeof(struct thin_lens_struct)); | |
thinLens->lensHeight = lensHeight; | |
thinLens->xCenter = xCenter; | |
thinLens->yCenter = yCenter; | |
thinLens->objectFocalPoint = xCenter - 100; | |
thinLens->imageFocalPoint = xCenter + 100; | |
return thinLens; | |
} | |
void DestroyThinLens(ThinLens thinlens) | |
{ | |
if(thinlens) | |
{ | |
free(thinlens); | |
} | |
} | |
float RadiansToDegrees(float radians) | |
{ | |
return radians * (180.0 / M_PI); | |
} | |
void DrawThinLens(Scene scene, ThinLens thinLens) | |
{ | |
float visualScale = 1.0f; | |
int lensThickness = 20; //Constant | |
int visualCenterX = thinLens->xCenter; | |
int visualCenterY = thinLens->yCenter; | |
//Draw thin lens center | |
filledCircleRGBA(scene->renderer, visualCenterX, visualCenterY, 2, 255, 255, 255, 255); | |
//Draw focal points | |
filledCircleRGBA(scene->renderer, thinLens->objectFocalPoint, visualCenterY, 3, 255, 255, 255, 255); | |
filledCircleRGBA(scene->renderer, thinLens->imageFocalPoint, visualCenterY, 3, 255, 255, 255, 255); | |
//Draw upper thin lens center height; | |
vlineRGBA(scene->renderer, visualCenterX, visualCenterY, visualCenterY - (thinLens->lensHeight/2), 255,255,255, 255); | |
//Draw bottom thin lens center height; | |
vlineRGBA(scene->renderer, visualCenterX, visualCenterY, visualCenterY + (thinLens->lensHeight/2), 255,255,255, 255); | |
//Draw top thin lens line | |
hlineRGBA(scene->renderer, visualCenterX + (lensThickness / 2), visualCenterX - (lensThickness / 2), visualCenterY - (thinLens->lensHeight/2), 0,0,255, 255); | |
//Draw top thin lens line | |
hlineRGBA(scene->renderer, visualCenterX + (lensThickness / 2), visualCenterX - (lensThickness / 2), visualCenterY + (thinLens->lensHeight/2), 0,0,255, 255); | |
//Right Arc | |
//Draw upper chord portion | |
vlineRGBA(scene->renderer, visualCenterX+(lensThickness / 2), visualCenterY, visualCenterY - (thinLens->lensHeight/2), 0,0,255, 255); | |
//Draw bottom chord portion | |
vlineRGBA(scene->renderer, visualCenterX+(lensThickness / 2), visualCenterY, visualCenterY + (thinLens->lensHeight/2), 0,0,255, 255); | |
int arcCenterY = visualCenterY; | |
int arcRadius = 200; | |
float oppositeOverHypoteneuse = (float)thinLens->lensHeight/2 / (float)arcRadius; | |
float arcAngleStartRadians = asin(oppositeOverHypoteneuse); | |
int arcAngleStartDegrees = -RadiansToDegrees(arcAngleStartRadians); | |
int arcAngleEnd = arcAngleStartDegrees * -1; | |
int triangleLength = sqrt((arcRadius * arcRadius) - ((thinLens->lensHeight/2)* (thinLens->lensHeight/2))); | |
int arcCenterX = visualCenterX-triangleLength + lensThickness / 2 ; | |
printf("%d %d %d\n",arcCenterX, triangleLength, thinLens->lensHeight/2); | |
arcRGBA(scene->renderer, arcCenterX, arcCenterY, (int)arcRadius,arcAngleStartDegrees, arcAngleEnd,0,0,255, 255); | |
//Draw upper chord portion | |
vlineRGBA(scene->renderer, visualCenterX-(lensThickness / 2), visualCenterY, visualCenterY - (thinLens->lensHeight/2), 0,0,255, 255); | |
//Draw bottom chord portion | |
vlineRGBA(scene->renderer, visualCenterX-(lensThickness / 2), visualCenterY, visualCenterY + (thinLens->lensHeight/2), 0,0,255, 255); | |
} | |
void DrawAxis(SDL_Renderer* renderer, int width, int height) | |
{ | |
int centerX = width / 2; | |
int centerY = height / 2; | |
thickLineRGBA(renderer, centerX, 0, centerX, height, 2, 0, 0, 0, 255); | |
thickLineRGBA(renderer, 0, centerY, width, centerY, 2, 0, 0, 0, 255); | |
} | |
SDL_Texture *LoadTexture(Scene scene, char *filepath) | |
{ | |
//Create a surface and check for errors | |
SDL_Surface *surface = SDL_LoadBMP(filepath); | |
if(surface == NULL){printf("Failed to load image: %s\n", SDL_GetError());} | |
//Create texture from surface | |
SDL_Texture *texture = SDL_CreateTextureFromSurface(scene->renderer, surface); | |
if(texture == NULL){printf("Failed to Create Texture From Surface: %s\n", SDL_GetError());} | |
//Free surface | |
SDL_FreeSurface(surface); | |
return texture; | |
} | |
Scene CreateScene(char *windowName, int windowWidth, int windowHeight) | |
{ | |
Scene scene = malloc(sizeof(struct scene_struct)); | |
scene->window = SDL_CreateWindow(windowName, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, | |
windowWidth, windowHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN); | |
scene->windowID = SDL_GetWindowID(scene->window); | |
scene->renderer = SDL_CreateRenderer(scene->window , -1, SDL_RENDERER_ACCELERATED); | |
scene->windowWidth = windowWidth; | |
scene->windowHeight= windowHeight; | |
SDL_RenderSetLogicalSize(scene->renderer, windowWidth, windowHeight); | |
SDL_SetRenderDrawBlendMode(scene->renderer, SDL_BLENDMODE_BLEND); | |
scene->texture = LoadTexture(scene, "./muragekibicho.bmp"); | |
return scene; | |
} | |
void DestroyScene(Scene scene) | |
{ | |
if(scene) | |
{ | |
if(scene->texture) | |
{ | |
SDL_DestroyTexture(scene->texture); | |
} | |
if(scene->renderer) | |
{ | |
SDL_DestroyRenderer(scene->renderer); | |
} | |
if(scene->window) | |
{ | |
SDL_DestroyWindow(scene->window); | |
} | |
free(scene); | |
} | |
} | |
void MainLoop(void *sceneArg) | |
{ | |
Scene scene = *(Scene*)sceneArg; | |
//Set Background color | |
SDL_SetRenderDrawColor(scene->renderer, 225, 225, 225, 255); | |
SDL_RenderClear(scene->renderer); | |
SDL_SetRenderDrawColor(scene->renderer, 0, 0, 0, 255); | |
DrawAxis(scene->renderer, scene->windowWidth, scene->windowHeight); | |
ThinLens lens0 = CreateThinLens(scene->windowHeight/2, scene->windowHeight/2, scene->windowWidth/2); | |
DrawThinLens(scene, lens0); | |
SDL_RenderPresent(scene->renderer); | |
SDL_Delay(1); | |
DestroyThinLens(lens0); | |
} | |
int main() | |
{ | |
int windowWidth = 512;int windowHeight= 512; | |
char *windowName = "Kibicho"; | |
SDL_Init(SDL_INIT_VIDEO); | |
Scene scene = CreateScene(windowName, windowWidth, windowHeight); | |
void *mainLoopArgument = scene; | |
#ifdef __EMSCRIPTEN__ | |
int fps = 0; | |
emscripten_set_main_loop_arg(MainLoop, &mainLoopArgument, fps, true); | |
#else | |
while(true) | |
{ | |
MainLoop(&mainLoopArgument); | |
} | |
#endif | |
DestroyScene(scene); | |
SDL_Quit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment