Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
emscripten: draw pixels with SDL_UpdateTexture
emcc test_pixel.c ^
-O2 ^
-s USE_SDL=2 ^
-s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS="[""png""]" ^
-s USE_SDL_TTF=2 ^
--preload-file assets ^
-o test_pixel.html
#include <stdbool.h>
#include <stdint.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_image.h>
#include <SDL/SDL_ttf.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
typedef struct display_t {
SDL_Texture *tex;
uint32_t *pixels;
SDL_Rect rect;
} Display;
typedef struct context_t {
SDL_Window *window;
SDL_Renderer *renderer;
Display *display;
} Context;
void Cleanup(Context *pCtx) {
SDL_Log("Cleanup\n");
if (pCtx->display) {
SDL_DestroyTexture(pCtx->display->tex);
free(pCtx->display->pixels);
free(pCtx->display);
}
if (pCtx->renderer)
SDL_DestroyRenderer(pCtx->renderer);
if (pCtx->window)
SDL_DestroyWindow(pCtx->window);
}
uint32_t CreateWindow(Context *pCtx) {
SDL_Log("CreateWindow\n");
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init() failed: %s\n", SDL_GetError());
return -1;
}
SDL_Window *window =
SDL_CreateWindow("sandbox", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
if (window == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindow() failed: %s\n", SDL_GetError());
return -1;
}
pCtx->window = window;
SDL_Renderer *renderer = SDL_CreateRenderer(
window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateRenderer() failed: %s\n", SDL_GetError());
return -1;
}
pCtx->renderer = renderer;
SDL_SetRenderDrawColor(renderer, 255, 255, 230, 255);
return 0;
}
void Display_init(Context *ctx) {
ctx->display = (Display *)malloc(sizeof(Display));
ctx->display->rect = (SDL_Rect){0,0,64,32};
uint32_t w = ctx->display->rect.w;
uint32_t h = ctx->display->rect.h;
SDL_Texture *texture = SDL_CreateTexture(ctx->renderer,
SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, w, h);
if (texture == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateTexture() failed: %s\n", SDL_GetError());
}
ctx->display->tex = texture;
// rgba = unsigned byte * 4 = uint32_t
uint32_t *pixels = (uint32_t *)malloc(sizeof(uint32_t) * w * h);
ctx->display->pixels = pixels;
}
void Display_update(Context *ctx) {
uint32_t *pixels = ctx->display->pixels;
if (!pixels)
return;
uint32_t w = ctx->display->rect.w;
uint32_t h = ctx->display->rect.h;
for (uint32_t y = 0; y < h; y++) {
uint32_t *pRow = pixels + (w * y); // pitch
for (uint32_t x = 0; x < w; x++) {
*pRow = 0xFF0000FF;
if (x > 10) {
*pRow = 0xFFFF00FF;
}
if (x > 25) {
*pRow = 0x000FFFFF;
}
pRow++;
}
}
}
void Display_draw(Context *ctx) {
SDL_UpdateTexture(ctx->display->tex, NULL, ctx->display->pixels, 64*sizeof(uint32_t));
//SDL_RenderCopy(ctx->renderer, ctx->tex1, NULL, &ctx->display->rect);
SDL_Rect r = {0, 0, 64*5, 32*5};
SDL_RenderCopy(ctx->renderer, ctx->display->tex, NULL, &r);
}
void input(Context *ctx) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
printf("call quit\n");
emscripten_cancel_main_loop();
Cleanup(ctx);
return;
}
}
}
void loop(void *arg) {
Context *ctx = (Context*)arg;
input(ctx);
SDL_RenderClear(ctx->renderer);
Display_update(ctx);
Display_draw(ctx);
SDL_RenderPresent(ctx->renderer);
}
int main() {
printf("begin\n");
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
// 初期化
Context ctx = {0};
CreateWindow(&ctx);
Display_init(&ctx);
// ループ
emscripten_set_main_loop_arg(loop, &ctx, -1, 1/*block*/);
SDL_Log("dont run this code by block.");
Cleanup(&ctx);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.