Files
lean-sdl3/examples/sdl-webcam-example.c
2026-07-08 22:28:38 -07:00

102 lines
2.8 KiB
C

#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
SDL_Window* window;
SDL_Renderer* renderer;
int width;
int height;
int camera_count;
SDL_CameraID* devices;
SDL_Camera* camera;
SDL_Texture* texture;
} AppState;
SDL_AppResult SDL_AppInit(void ** appstate, int argc, char** argv) {
AppState* app_state = malloc(sizeof(AppState));
*app_state = (AppState){
.width = 800,
.height = 600,
};
*appstate = app_state;
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA)) {
SDL_Log("couldn't initialize properly: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_CreateWindowAndRenderer("SDL3 Camera Demo", app_state->width, app_state->height, 0, &(app_state->window), &(app_state->renderer))) {
SDL_Log("couldn't initialize window/renderer properly: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
SDL_CameraID* devices = SDL_GetCameras(&app_state->camera_count);
if (devices == NULL) {
SDL_Log("Can't enumerate cameras: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
SDL_Log("Found %d cameras", app_state->camera_count);
app_state->devices = devices;
if (app_state->camera_count == 0) {
return SDL_APP_FAILURE;
}
app_state->camera = SDL_OpenCamera(devices[0], NULL);
if (app_state->camera == NULL) {
SDL_Log("Can't open camera: %s", SDL_GetError());
}
SDL_CameraSpec spec;
SDL_GetCameraFormat(app_state->camera, &spec);
int n = spec.framerate_numerator;
int d = spec.framerate_denominator;
SDL_Log("Framerate: FPS %d/%d, w: %d, h: %d", n, d, spec.width, spec.height);
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppIterate(void* appstate) {
AppState* app_state = appstate;
SDL_Surface* frame = SDL_AcquireCameraFrame(app_state->camera, NULL);
if (frame != NULL) {
if (app_state->texture == NULL) {
app_state->texture = SDL_CreateTexture(app_state->renderer, frame->format, SDL_TEXTUREACCESS_STREAMING, frame->w, frame->h);
} else {
SDL_UpdateTexture(app_state->texture, NULL, frame->pixels, frame->pitch);
}
SDL_ReleaseCameraFrame(app_state->camera, frame);
}
SDL_SetRenderDrawColorFloat(app_state->renderer, 0.4f, 0.6f, 1.0f, SDL_ALPHA_OPAQUE_FLOAT);
SDL_RenderClear(app_state->renderer);
if (app_state->texture) {
SDL_RenderTexture(app_state->renderer, app_state->texture, NULL, NULL);
}
SDL_RenderPresent(app_state->renderer);
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event *event) {
if (event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS;
}
return SDL_APP_CONTINUE;
}
void SDL_AppQuit(void* appstate, SDL_AppResult result) {}