Skip to content

Instantly share code, notes, and snippets.

@MurageKibicho
Created July 17, 2025 15:06
Show Gist options
  • Save MurageKibicho/250444a28cc81ab67182cd5279014cdd to your computer and use it in GitHub Desktop.
Save MurageKibicho/250444a28cc81ab67182cd5279014cdd to your computer and use it in GitHub Desktop.
Texture camera second step
#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