Squashed 'external/ircolib/' changes from ce3cd726c..de6e324bd
de6e324bdseparate emu thread10d3daf86Roms List improvements95d202f37Let's make the rom list process on a separate thread so the emulator doesnt take ages to load.fc306967fWow the ROM Header was just completely busted. Game list view works nowbad1691eefuck this shit2b59e5f46game list in progressd26417b83remappable inputs in progressac4af8106inpute72abc240update readme430139dc9Qt6 frontend3080d4d45Fix this small bug too08cd13b85Cop0 unused functions do not actually pose a threat (as per manual). They don't do anything, so shall we.61bb4fb44make idle loop detection a little more specific with where the load goesb037de4c3SAZDFsdff12e81e73eneed to figure out why n64-systemtest loops indefinitely at some address that appears to be valid (i think it's me not invalidating the cache properly)204f0e13bidle skipping seems to work!cb8bb634asdkfjlasdf58e5c89c1Fix compilation issue on my machine (no idea)24fb2898eattempting more serious idle skipping214719577Place rsp.Step inside cached interpreter. Gains about 3 more fpsbb97dcc23mmmmm920b77d38wjkhasdfjhkasdf430ccdab4it's a start...4f42a673aCached interpreter plays Mario 64. Start looking into RSP as wellc9a030787idle skipping works!5fbda03cenew idea366637abaIdle skipping... maybe?609fa2fb0Cache instructions implemented but broken lmao. Commented out for nowe140a6d12- Stop using inheritance for CPU, instead use composition. - Introduce KAIZEN_JIT_ENABLED optional define instead of relying on __aarch64__ and the like. - More cache work68e613057prep cache impl811b4d809fix clang formatfda755f7didkd5024ebbfsmall MI refactor in preparation of (eventually) implementing the RDRAM interface properly694b45341Merge commit '206dcdedf195fb320913584180edb12c7731e396' as 'external/SDL'206dcdedfSquashed 'external/SDL/' content from commit 4d17b99d0a4d16e1cb4need to update sdl848b19920Fix compilation errordb61b5299Merge commit 'e94a94559f28e49678fbcf72199a5258137b0fe9' as 'external/imgui'e94a94559Squashed 'external/imgui/' content from commit 02e9b8cac52edb3757need to update imguic1a705e86Emulate weird JALR behaviour4b4c32f4bFix exception for "unusable COP1" in 4 instructions i missed accidentally (again)df5828142Bug putting 0s in the log everywheref8b580048Make isviewer a sink to file8241e9735Fix exception for "unusable COP1" in 4 instructions i missed accidentallyb29715f20small changesd9a620bc1make use of my new small utility library0d1aa938eAdd 'external/ircolib/' from commit 'ce3cd726c8df8388d554abf8bb55d55020eb4450'e64eb40b3Fuck git git-subtree-dir: external/ircolib git-subtree-split:de6e324bde
@@ -0,0 +1,3 @@
|
||||
This example code creates an SDL window and renderer, and then clears the
|
||||
window to a different color every frame, so you'll effectively get a window
|
||||
that's smoothly fading between colors.
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This example code creates an SDL window and renderer, and then clears the
|
||||
* window to a different color every frame, so you'll effectively get a window
|
||||
* that's smoothly fading between colors.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_SetAppMetadata("Example Renderer Clear", "1.0", "com.example.renderer-clear");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/clear", 640, 480, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
const double now = ((double)SDL_GetTicks()) / 1000.0; /* convert from milliseconds to seconds. */
|
||||
/* choose the color for the frame we will draw. The sine wave trick makes it fade between colors smoothly. */
|
||||
const float red = (float) (0.5 + 0.5 * SDL_sin(now));
|
||||
const float green = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 2 / 3));
|
||||
const float blue = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 4 / 3));
|
||||
SDL_SetRenderDrawColorFloat(renderer, red, green, blue, SDL_ALPHA_OPAQUE_FLOAT); /* new color, full alpha. */
|
||||
|
||||
/* clear the window to the draw color. */
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
/* put the newly-cleared rendering on the screen. */
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,7 @@
|
||||
This example creates an SDL window and renderer, and then draws some lines,
|
||||
rectangles and points to it every frame.
|
||||
|
||||
This is just a quick overview of simple drawing primitives; further examples
|
||||
will explore them in more detail.
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some lines,
|
||||
* rectangles and points to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_FPoint points[500];
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Primitives", "1.0", "com.example.renderer-primitives");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/primitives", 640, 480, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* set up some random points */
|
||||
for (i = 0; i < SDL_arraysize(points); i++) {
|
||||
points[i].x = (SDL_randf() * 440.0f) + 100.0f;
|
||||
points[i].y = (SDL_randf() * 280.0f) + 100.0f;
|
||||
}
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_FRect rect;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 33, 33, 33, SDL_ALPHA_OPAQUE); /* dark gray, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* draw a filled rectangle in the middle of the canvas. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 255, SDL_ALPHA_OPAQUE); /* blue, full alpha */
|
||||
rect.x = rect.y = 100;
|
||||
rect.w = 440;
|
||||
rect.h = 280;
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
|
||||
/* draw some points across the canvas. */
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); /* red, full alpha */
|
||||
SDL_RenderPoints(renderer, points, SDL_arraysize(points));
|
||||
|
||||
/* draw a unfilled rectangle in-set a little bit. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE); /* green, full alpha */
|
||||
rect.x += 30;
|
||||
rect.y += 30;
|
||||
rect.w -= 60;
|
||||
rect.h -= 60;
|
||||
SDL_RenderRect(renderer, &rect);
|
||||
|
||||
/* draw two lines in an X across the whole canvas. */
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 0, SDL_ALPHA_OPAQUE); /* yellow, full alpha */
|
||||
SDL_RenderLine(renderer, 0, 0, 640, 480);
|
||||
SDL_RenderLine(renderer, 0, 480, 640, 0);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, and then draws a something
|
||||
roughly like a Christmas tree with nothing but lines, every frame.
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some lines
|
||||
* to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_SetAppMetadata("Example Renderer Lines", "1.0", "com.example.renderer-lines");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/lines", 640, 480, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Lines (line segments, really) are drawn in terms of points: a set of
|
||||
X and Y coordinates, one set for each end of the line.
|
||||
(0, 0) is the top left of the window, and larger numbers go down
|
||||
and to the right. This isn't how geometry works, but this is pretty
|
||||
standard in 2D graphics. */
|
||||
static const SDL_FPoint line_points[] = {
|
||||
{ 100, 354 }, { 220, 230 }, { 140, 230 }, { 320, 100 }, { 500, 230 },
|
||||
{ 420, 230 }, { 540, 354 }, { 400, 354 }, { 100, 354 }
|
||||
};
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 100, 100, 100, SDL_ALPHA_OPAQUE); /* grey, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* You can draw lines, one at a time, like these brown ones... */
|
||||
SDL_SetRenderDrawColor(renderer, 127, 49, 32, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderLine(renderer, 240, 450, 400, 450);
|
||||
SDL_RenderLine(renderer, 240, 356, 400, 356);
|
||||
SDL_RenderLine(renderer, 240, 356, 240, 450);
|
||||
SDL_RenderLine(renderer, 400, 356, 400, 450);
|
||||
|
||||
/* You can also draw a series of connected lines in a single batch... */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderLines(renderer, line_points, SDL_arraysize(line_points));
|
||||
|
||||
/* here's a bunch of lines drawn out from a center point in a circle. */
|
||||
/* we randomize the color of each line, so it functions as animation. */
|
||||
for (i = 0; i < 360; i++) {
|
||||
const float size = 30.0f;
|
||||
const float x = 320.0f;
|
||||
const float y = 95.0f - (size / 2.0f);
|
||||
const float r = (float) i * (SDL_PI_F / 180.0f);
|
||||
SDL_SetRenderDrawColor(renderer, SDL_rand(256), SDL_rand(256), SDL_rand(256), SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderLine(renderer, x, y, x + SDL_cosf(r) * size, y + SDL_sinf(r) * size);
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, and then draws a bunch of
|
||||
single points, moving across the screen.
|
||||
|
||||
|
After Width: | Height: | Size: 152 KiB |
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some points
|
||||
* to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static Uint64 last_time = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
#define NUM_POINTS 500
|
||||
#define MIN_PIXELS_PER_SECOND 30 /* move at least this many pixels per second. */
|
||||
#define MAX_PIXELS_PER_SECOND 60 /* move this many pixels per second at most. */
|
||||
|
||||
/* (track everything as parallel arrays instead of a array of structs,
|
||||
so we can pass the coordinates to the renderer in a single function call.) */
|
||||
|
||||
/* Points are plotted as a set of X and Y coordinates.
|
||||
(0, 0) is the top left of the window, and larger numbers go down
|
||||
and to the right. This isn't how geometry works, but this is pretty
|
||||
standard in 2D graphics. */
|
||||
static SDL_FPoint points[NUM_POINTS];
|
||||
static float point_speeds[NUM_POINTS];
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Points", "1.0", "com.example.renderer-points");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/points", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* set up the data for a bunch of points. */
|
||||
for (i = 0; i < SDL_arraysize(points); i++) {
|
||||
points[i].x = SDL_randf() * ((float) WINDOW_WIDTH);
|
||||
points[i].y = SDL_randf() * ((float) WINDOW_HEIGHT);
|
||||
point_speeds[i] = MIN_PIXELS_PER_SECOND + (SDL_randf() * (MAX_PIXELS_PER_SECOND - MIN_PIXELS_PER_SECOND));
|
||||
}
|
||||
|
||||
last_time = SDL_GetTicks();
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
const float elapsed = ((float) (now - last_time)) / 1000.0f; /* seconds since last iteration */
|
||||
int i;
|
||||
|
||||
/* let's move all our points a little for a new frame. */
|
||||
for (i = 0; i < SDL_arraysize(points); i++) {
|
||||
const float distance = elapsed * point_speeds[i];
|
||||
points[i].x += distance;
|
||||
points[i].y += distance;
|
||||
if ((points[i].x >= WINDOW_WIDTH) || (points[i].y >= WINDOW_HEIGHT)) {
|
||||
/* off the screen; restart it elsewhere! */
|
||||
if (SDL_rand(2)) {
|
||||
points[i].x = SDL_randf() * ((float) WINDOW_WIDTH);
|
||||
points[i].y = 0.0f;
|
||||
} else {
|
||||
points[i].x = 0.0f;
|
||||
points[i].y = SDL_randf() * ((float) WINDOW_HEIGHT);
|
||||
}
|
||||
point_speeds[i] = MIN_PIXELS_PER_SECOND + (SDL_randf() * (MAX_PIXELS_PER_SECOND - MIN_PIXELS_PER_SECOND));
|
||||
}
|
||||
}
|
||||
|
||||
last_time = now;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */
|
||||
SDL_RenderPoints(renderer, points, SDL_arraysize(points)); /* draw all the points! */
|
||||
|
||||
/* You can also draw single points with SDL_RenderPoint(), but it's
|
||||
cheaper (sometimes significantly so) to do them all at once. */
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 7.9 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, and then draws a few
|
||||
rectangles that change size each frame.
|
||||
|
||||
|
After Width: | Height: | Size: 74 KiB |
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some
|
||||
* rectangles to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_SetAppMetadata("Example Renderer Rectangles", "1.0", "com.example.renderer-rectangles");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/rectangles", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_FRect rects[16];
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
int i;
|
||||
|
||||
/* we'll have the rectangles grow and shrink over a few seconds. */
|
||||
const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
|
||||
const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* Rectangles are comprised of set of X and Y coordinates, plus width and
|
||||
height. (0, 0) is the top left of the window, and larger numbers go
|
||||
down and to the right. This isn't how geometry works, but this is
|
||||
pretty standard in 2D graphics. */
|
||||
|
||||
/* Let's draw a single rectangle (square, really). */
|
||||
rects[0].x = rects[0].y = 100;
|
||||
rects[0].w = rects[0].h = 100 + (100 * scale);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE); /* red, full alpha */
|
||||
SDL_RenderRect(renderer, &rects[0]);
|
||||
|
||||
/* Now let's draw several rectangles with one function call. */
|
||||
for (i = 0; i < 3; i++) {
|
||||
const float size = (i+1) * 50.0f;
|
||||
rects[i].w = rects[i].h = size + (size * scale);
|
||||
rects[i].x = (WINDOW_WIDTH - rects[i].w) / 2; /* center it. */
|
||||
rects[i].y = (WINDOW_HEIGHT - rects[i].h) / 2; /* center it. */
|
||||
}
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE); /* green, full alpha */
|
||||
SDL_RenderRects(renderer, rects, 3); /* draw three rectangles at once */
|
||||
|
||||
/* those were rectangle _outlines_, really. You can also draw _filled_ rectangles! */
|
||||
rects[0].x = 400;
|
||||
rects[0].y = 50;
|
||||
rects[0].w = 100 + (100 * scale);
|
||||
rects[0].h = 50 + (50 * scale);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 255, SDL_ALPHA_OPAQUE); /* blue, full alpha */
|
||||
SDL_RenderFillRect(renderer, &rects[0]);
|
||||
|
||||
/* ...and also fill a bunch of rectangles at once... */
|
||||
for (i = 0; i < SDL_arraysize(rects); i++) {
|
||||
const float w = (float) (WINDOW_WIDTH / SDL_arraysize(rects));
|
||||
const float h = i * 8.0f;
|
||||
rects[i].x = i * w;
|
||||
rects[i].y = WINDOW_HEIGHT - h;
|
||||
rects[i].w = w;
|
||||
rects[i].h = h;
|
||||
}
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */
|
||||
SDL_RenderFillRects(renderer, rects, SDL_arraysize(rects));
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, loads a texture from a
|
||||
.png file, and then draws it a few times each frame.
|
||||
|
||||
|
After Width: | Height: | Size: 592 KiB |
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some
|
||||
* textures to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static int texture_width = 0;
|
||||
static int texture_height = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Textures", "1.0", "com.example.renderer-textures");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/textures", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a png file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load png: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture_width = surface->w;
|
||||
texture_height = surface->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_FRect dst_rect;
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
|
||||
/* we'll have some textures move around over a few seconds. */
|
||||
const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
|
||||
const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* Just draw the static texture a few times. You can think of it like a
|
||||
stamp, there isn't a limit to the number of times you can draw with it. */
|
||||
|
||||
/* top left */
|
||||
dst_rect.x = (100.0f * scale);
|
||||
dst_rect.y = 0.0f;
|
||||
dst_rect.w = (float) texture_width;
|
||||
dst_rect.h = (float) texture_height;
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
/* center this one. */
|
||||
dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
|
||||
dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
|
||||
dst_rect.w = (float) texture_width;
|
||||
dst_rect.h = (float) texture_height;
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
/* bottom right. */
|
||||
dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) - (100.0f * scale);
|
||||
dst_rect.y = (float) (WINDOW_HEIGHT - texture_height);
|
||||
dst_rect.w = (float) texture_width;
|
||||
dst_rect.h = (float) texture_height;
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 233 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, then a streaming texture that
|
||||
it will update every frame before drawing it to the screen.
|
||||
|
||||
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws a streaming
|
||||
* texture to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
|
||||
#define TEXTURE_SIZE 150
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_SetAppMetadata("Example Renderer Streaming Textures", "1.0", "com.example.renderer-streaming-textures");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/streaming-textures", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create streaming texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_FRect dst_rect;
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
SDL_Surface *surface = NULL;
|
||||
|
||||
/* we'll have some color move around over a few seconds. */
|
||||
const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
|
||||
const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
|
||||
|
||||
/* To update a streaming texture, you need to lock it first. This gets you access to the pixels.
|
||||
Note that this is considered a _write-only_ operation: the buffer you get from locking
|
||||
might not actually have the existing contents of the texture, and you have to write to every
|
||||
locked pixel! */
|
||||
|
||||
/* You can use SDL_LockTexture() to get an array of raw pixels, but we're going to use
|
||||
SDL_LockTextureToSurface() here, because it wraps that array in a temporary SDL_Surface,
|
||||
letting us use the surface drawing functions instead of lighting up individual pixels. */
|
||||
if (SDL_LockTextureToSurface(texture, NULL, &surface)) {
|
||||
SDL_Rect r;
|
||||
SDL_FillSurfaceRect(surface, NULL, SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, 0, 0, 0)); /* make the whole surface black */
|
||||
r.w = TEXTURE_SIZE;
|
||||
r.h = TEXTURE_SIZE / 10;
|
||||
r.x = 0;
|
||||
r.y = (int) (((float) (TEXTURE_SIZE - r.h)) * ((scale + 1.0f) / 2.0f));
|
||||
SDL_FillSurfaceRect(surface, &r, SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, 0, 255, 0)); /* make a strip of the surface green */
|
||||
SDL_UnlockTexture(texture); /* upload the changes (and frees the temporary surface)! */
|
||||
}
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 66, 66, 66, SDL_ALPHA_OPAQUE); /* grey, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* Just draw the static texture a few times. You can think of it like a
|
||||
stamp, there isn't a limit to the number of times you can draw with it. */
|
||||
|
||||
/* Center this one. It'll draw the latest version of the texture we drew while it was locked. */
|
||||
dst_rect.x = ((float) (WINDOW_WIDTH - TEXTURE_SIZE)) / 2.0f;
|
||||
dst_rect.y = ((float) (WINDOW_HEIGHT - TEXTURE_SIZE)) / 2.0f;
|
||||
dst_rect.w = dst_rect.h = (float) TEXTURE_SIZE;
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, loads a texture from a .png
|
||||
file, and then draws it, rotating around the center of the screen.
|
||||
|
||||
|
After Width: | Height: | Size: 306 KiB |
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some
|
||||
* rotated textures to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static int texture_width = 0;
|
||||
static int texture_height = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Rotating Textures", "1.0", "com.example.renderer-rotating-textures");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/rotating-textures", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a bitmap file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture_width = surface->w;
|
||||
texture_height = surface->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_FPoint center;
|
||||
SDL_FRect dst_rect;
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
|
||||
/* we'll have a texture rotate around over 2 seconds (2000 milliseconds). 360 degrees in a circle! */
|
||||
const float rotation = (((float) ((int) (now % 2000))) / 2000.0f) * 360.0f;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* Center this one, and draw it with some rotation so it spins! */
|
||||
dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
|
||||
dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
|
||||
dst_rect.w = (float) texture_width;
|
||||
dst_rect.h = (float) texture_height;
|
||||
/* rotate it around the center of the texture; you can rotate it from a different point, too! */
|
||||
center.x = texture_width / 2.0f;
|
||||
center.y = texture_height / 2.0f;
|
||||
SDL_RenderTextureRotated(renderer, texture, NULL, &dst_rect, rotation, ¢er, SDL_FLIP_NONE);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 89 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, loads a texture from a .png
|
||||
file, and then draws it, scaling it up and down.
|
||||
|
||||
|
After Width: | Height: | Size: 311 KiB |
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some
|
||||
* textures to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static int texture_width = 0;
|
||||
static int texture_height = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Scaling Textures", "1.0", "com.example.renderer-scaling-textures");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/scaling-textures", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a bitmap file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture_width = surface->w;
|
||||
texture_height = surface->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_FRect dst_rect;
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
|
||||
/* we'll have the texture grow and shrink over a few seconds. */
|
||||
const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
|
||||
const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* center this one and make it grow and shrink. */
|
||||
dst_rect.w = (float) texture_width + (texture_width * scale);
|
||||
dst_rect.h = (float) texture_height + (texture_height * scale);
|
||||
dst_rect.x = (WINDOW_WIDTH - dst_rect.w) / 2.0f;
|
||||
dst_rect.y = (WINDOW_HEIGHT - dst_rect.h) / 2.0f;
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 82 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, loads a texture from a .png
|
||||
file, and then draws geometry (arbitrary polygons) using it.
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some
|
||||
* geometry (arbitrary polygons) to it every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static int texture_width = 0;
|
||||
static int texture_height = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Geometry", "1.0", "com.example.renderer-geometry");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/geometry", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a bitmap file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture_width = surface->w;
|
||||
texture_height = surface->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
|
||||
/* we'll have the triangle grow and shrink over a few seconds. */
|
||||
const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f;
|
||||
const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction;
|
||||
const float size = 200.0f + (200.0f * scale);
|
||||
|
||||
SDL_Vertex vertices[4];
|
||||
int i;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* Draw a single triangle with a different color at each vertex. Center this one and make it grow and shrink. */
|
||||
/* You always draw triangles with this, but you can string triangles together to form polygons. */
|
||||
SDL_zeroa(vertices);
|
||||
vertices[0].position.x = ((float) WINDOW_WIDTH) / 2.0f;
|
||||
vertices[0].position.y = (((float) WINDOW_HEIGHT) - size) / 2.0f;
|
||||
vertices[0].color.r = 1.0f;
|
||||
vertices[0].color.a = 1.0f;
|
||||
vertices[1].position.x = (((float) WINDOW_WIDTH) + size) / 2.0f;
|
||||
vertices[1].position.y = (((float) WINDOW_HEIGHT) + size) / 2.0f;
|
||||
vertices[1].color.g = 1.0f;
|
||||
vertices[1].color.a = 1.0f;
|
||||
vertices[2].position.x = (((float) WINDOW_WIDTH) - size) / 2.0f;
|
||||
vertices[2].position.y = (((float) WINDOW_HEIGHT) + size) / 2.0f;
|
||||
vertices[2].color.b = 1.0f;
|
||||
vertices[2].color.a = 1.0f;
|
||||
|
||||
SDL_RenderGeometry(renderer, NULL, vertices, 3, NULL, 0);
|
||||
|
||||
/* you can also map a texture to the geometry! Texture coordinates go from 0.0f to 1.0f. That will be the location
|
||||
in the texture bound to this vertex. */
|
||||
SDL_zeroa(vertices);
|
||||
vertices[0].position.x = 10.0f;
|
||||
vertices[0].position.y = 10.0f;
|
||||
vertices[0].color.r = vertices[0].color.g = vertices[0].color.b = vertices[0].color.a = 1.0f;
|
||||
vertices[0].tex_coord.x = 0.0f;
|
||||
vertices[0].tex_coord.y = 0.0f;
|
||||
vertices[1].position.x = 150.0f;
|
||||
vertices[1].position.y = 10.0f;
|
||||
vertices[1].color.r = vertices[1].color.g = vertices[1].color.b = vertices[1].color.a = 1.0f;
|
||||
vertices[1].tex_coord.x = 1.0f;
|
||||
vertices[1].tex_coord.y = 0.0f;
|
||||
vertices[2].position.x = 10.0f;
|
||||
vertices[2].position.y = 150.0f;
|
||||
vertices[2].color.r = vertices[2].color.g = vertices[2].color.b = vertices[2].color.a = 1.0f;
|
||||
vertices[2].tex_coord.x = 0.0f;
|
||||
vertices[2].tex_coord.y = 1.0f;
|
||||
SDL_RenderGeometry(renderer, texture, vertices, 3, NULL, 0);
|
||||
|
||||
/* Did that only draw half of the texture? You can do multiple triangles sharing some vertices,
|
||||
using indices, to get the whole thing on the screen: */
|
||||
|
||||
/* Let's just move this over so it doesn't overlap... */
|
||||
for (i = 0; i < 3; i++) {
|
||||
vertices[i].position.x += 450;
|
||||
}
|
||||
|
||||
/* we need one more vertex, since the two triangles can share two of them. */
|
||||
vertices[3].position.x = 600.0f;
|
||||
vertices[3].position.y = 150.0f;
|
||||
vertices[3].color.r = vertices[3].color.g = vertices[3].color.b = vertices[3].color.a = 1.0f;
|
||||
vertices[3].tex_coord.x = 1.0f;
|
||||
vertices[3].tex_coord.y = 1.0f;
|
||||
|
||||
/* And an index to tell it to reuse some of the vertices between triangles... */
|
||||
{
|
||||
/* 4 vertices, but 6 actual places they used. Indices need less bandwidth to transfer and can reorder vertices easily! */
|
||||
const int indices[] = { 0, 1, 2, 1, 2, 3 };
|
||||
SDL_RenderGeometry(renderer, texture, vertices, 4, indices, SDL_arraysize(indices));
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 56 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, loads a texture from a
|
||||
.png file, and then draws it a few times each frame, adjusting the colors.
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some
|
||||
* textures to it every frame, adjusting their color.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static int texture_width = 0;
|
||||
static int texture_height = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Color Mods", "1.0", "com.example.renderer-color-mods");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/color-mods", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a bitmap file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture_width = surface->w;
|
||||
texture_height = surface->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_FRect dst_rect;
|
||||
const double now = ((double)SDL_GetTicks()) / 1000.0; /* convert from milliseconds to seconds. */
|
||||
/* choose the modulation values for the center texture. The sine wave trick makes it fade between colors smoothly. */
|
||||
const float red = (float) (0.5 + 0.5 * SDL_sin(now));
|
||||
const float green = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 2 / 3));
|
||||
const float blue = (float) (0.5 + 0.5 * SDL_sin(now + SDL_PI_D * 4 / 3));
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* Just draw the static texture a few times. You can think of it like a
|
||||
stamp, there isn't a limit to the number of times you can draw with it. */
|
||||
|
||||
/* Color modulation multiplies each pixel's red, green, and blue intensities by the mod values,
|
||||
so multiplying by 1.0f will leave a color intensity alone, 0.0f will shut off that color
|
||||
completely, etc. */
|
||||
|
||||
/* top left; let's make this one blue! */
|
||||
dst_rect.x = 0.0f;
|
||||
dst_rect.y = 0.0f;
|
||||
dst_rect.w = (float) texture_width;
|
||||
dst_rect.h = (float) texture_height;
|
||||
SDL_SetTextureColorModFloat(texture, 0.0f, 0.0f, 1.0f); /* kill all red and green. */
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
/* center this one, and have it cycle through red/green/blue modulations. */
|
||||
dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
|
||||
dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
|
||||
dst_rect.w = (float) texture_width;
|
||||
dst_rect.h = (float) texture_height;
|
||||
SDL_SetTextureColorModFloat(texture, red, green, blue);
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
/* bottom right; let's make this one red! */
|
||||
dst_rect.x = (float) (WINDOW_WIDTH - texture_width);
|
||||
dst_rect.y = (float) (WINDOW_HEIGHT - texture_height);
|
||||
dst_rect.w = (float) texture_width;
|
||||
dst_rect.h = (float) texture_height;
|
||||
SDL_SetTextureColorModFloat(texture, 1.0f, 0.0f, 0.0f); /* kill all green and blue. */
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 272 KiB |
|
After Width: | Height: | Size: 120 KiB |
@@ -0,0 +1,4 @@
|
||||
This example creates an SDL window and renderer, loads a texture
|
||||
from a .png file, and then draws it a few times each frame, adjusting
|
||||
the viewport before each draw.
|
||||
|
||||
|
After Width: | Height: | Size: 143 KiB |
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some
|
||||
* textures to it every frame, adjusting the viewport.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static int texture_width = 0;
|
||||
static int texture_height = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Viewport", "1.0", "com.example.renderer-viewport");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/viewport", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a bitmap file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture_width = surface->w;
|
||||
texture_height = surface->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
SDL_FRect dst_rect = { 0, 0, (float) texture_width, (float) texture_height };
|
||||
SDL_Rect viewport;
|
||||
|
||||
/* Setting a viewport has the effect of limiting the area that rendering
|
||||
can happen, and making coordinate (0, 0) live somewhere else in the
|
||||
window. It does _not_ scale rendering to fit the viewport. */
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* Draw once with the whole window as the viewport. */
|
||||
viewport.x = 0;
|
||||
viewport.y = 0;
|
||||
viewport.w = WINDOW_WIDTH / 2;
|
||||
viewport.h = WINDOW_HEIGHT / 2;
|
||||
SDL_SetRenderViewport(renderer, NULL); /* NULL means "use the whole window" */
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
/* top right quarter of the window. */
|
||||
viewport.x = WINDOW_WIDTH / 2;
|
||||
viewport.y = WINDOW_HEIGHT / 2;
|
||||
viewport.w = WINDOW_WIDTH / 2;
|
||||
viewport.h = WINDOW_HEIGHT / 2;
|
||||
SDL_SetRenderViewport(renderer, &viewport);
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
/* bottom 20% of the window. Note it clips the width! */
|
||||
viewport.x = 0;
|
||||
viewport.y = WINDOW_HEIGHT - (WINDOW_HEIGHT / 5);
|
||||
viewport.w = WINDOW_WIDTH / 5;
|
||||
viewport.h = WINDOW_HEIGHT / 5;
|
||||
SDL_SetRenderViewport(renderer, &viewport);
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
/* what happens if you try to draw above the viewport? It should clip! */
|
||||
viewport.x = 100;
|
||||
viewport.y = 200;
|
||||
viewport.w = WINDOW_WIDTH;
|
||||
viewport.h = WINDOW_HEIGHT;
|
||||
SDL_SetRenderViewport(renderer, &viewport);
|
||||
dst_rect.y = -50;
|
||||
SDL_RenderTexture(renderer, texture, NULL, &dst_rect);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
This example creates an SDL window and renderer, loads a texture
|
||||
from a .png file, and stretches it across the window. Each frame, we move
|
||||
the clipping rectangle around, so only a small square of the texture is
|
||||
actually drawn.
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws a scene
|
||||
* to it every frame, while sliding around a clipping rectangle.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
#define CLIPRECT_SIZE 250
|
||||
#define CLIPRECT_SPEED 200 /* pixels per second */
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static SDL_FPoint cliprect_position;
|
||||
static SDL_FPoint cliprect_direction;
|
||||
static Uint64 last_time = 0;
|
||||
|
||||
/* A lot of this program is examples/renderer/02-primitives, so we have a good
|
||||
visual that we can slide a clip rect around. The actual new magic in here
|
||||
is the SDL_SetRenderClipRect() function. */
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Clipping Rectangle", "1.0", "com.example.renderer-cliprect");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/cliprect", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
cliprect_direction.x = cliprect_direction.y = 1.0f;
|
||||
|
||||
last_time = SDL_GetTicks();
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a bitmap file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
const SDL_Rect cliprect = { (int) SDL_roundf(cliprect_position.x), (int) SDL_roundf(cliprect_position.y), CLIPRECT_SIZE, CLIPRECT_SIZE };
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
const float elapsed = ((float) (now - last_time)) / 1000.0f; /* seconds since last iteration */
|
||||
const float distance = elapsed * CLIPRECT_SPEED;
|
||||
|
||||
/* Set a new clipping rectangle position */
|
||||
cliprect_position.x += distance * cliprect_direction.x;
|
||||
if (cliprect_position.x < -CLIPRECT_SIZE) {
|
||||
cliprect_position.x = -CLIPRECT_SIZE;
|
||||
cliprect_direction.x = 1.0f;
|
||||
} else if (cliprect_position.x >= WINDOW_WIDTH) {
|
||||
cliprect_position.x = WINDOW_WIDTH - 1;
|
||||
cliprect_direction.x = -1.0f;
|
||||
}
|
||||
|
||||
cliprect_position.y += distance * cliprect_direction.y;
|
||||
if (cliprect_position.y < -CLIPRECT_SIZE) {
|
||||
cliprect_position.y = -CLIPRECT_SIZE;
|
||||
cliprect_direction.y = 1.0f;
|
||||
} else if (cliprect_position.y >= WINDOW_HEIGHT) {
|
||||
cliprect_position.y = WINDOW_HEIGHT - 1;
|
||||
cliprect_direction.y = -1.0f;
|
||||
}
|
||||
SDL_SetRenderClipRect(renderer, &cliprect);
|
||||
|
||||
last_time = now;
|
||||
|
||||
/* okay, now draw! */
|
||||
|
||||
/* Note that SDL_RenderClear is _not_ affected by the clipping rectangle! */
|
||||
SDL_SetRenderDrawColor(renderer, 33, 33, 33, SDL_ALPHA_OPAQUE); /* grey, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* stretch the texture across the entire window. Only the piece in the
|
||||
clipping rectangle will actually render, though! */
|
||||
SDL_RenderTexture(renderer, texture, NULL, NULL);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 85 KiB |
@@ -0,0 +1,12 @@
|
||||
This example creates an SDL window and renderer, and draws a
|
||||
rotating texture to it, reads back the rendered pixels, converts them to
|
||||
black and white, and then draws the converted image to a corner of the
|
||||
screen.
|
||||
|
||||
This isn't necessarily an efficient thing to do--in real life one might
|
||||
want to do this sort of thing with a render target--but it's just a visual
|
||||
example of how to use SDL_RenderReadPixels().
|
||||
|
||||
A better, but less visual, use of SDL_RenderReadPixels() is to make
|
||||
screenshots: you grab the current contents of the screen, and save the pixels
|
||||
as a bitmap file or whatever.
|
||||
|
After Width: | Height: | Size: 471 KiB |
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and draws a
|
||||
* rotating texture to it, reads back the rendered pixels, converts them to
|
||||
* black and white, and then draws the converted image to a corner of the
|
||||
* screen.
|
||||
*
|
||||
* This isn't necessarily an efficient thing to do--in real life one might
|
||||
* want to do this sort of thing with a render target--but it's just a visual
|
||||
* example of how to use SDL_RenderReadPixels().
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static int texture_width = 0;
|
||||
static int texture_height = 0;
|
||||
static SDL_Texture *converted_texture = NULL;
|
||||
static int converted_texture_width = 0;
|
||||
static int converted_texture_height = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Read Pixels", "1.0", "com.example.renderer-read-pixels");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/read-pixels", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a bitmap file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture_width = surface->w;
|
||||
texture_height = surface->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
SDL_Surface *surface;
|
||||
SDL_FPoint center;
|
||||
SDL_FRect dst_rect;
|
||||
|
||||
/* we'll have a texture rotate around over 2 seconds (2000 milliseconds). 360 degrees in a circle! */
|
||||
const float rotation = (((float) ((int) (now % 2000))) / 2000.0f) * 360.0f;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
/* Center this one, and draw it with some rotation so it spins! */
|
||||
dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f;
|
||||
dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f;
|
||||
dst_rect.w = (float) texture_width;
|
||||
dst_rect.h = (float) texture_height;
|
||||
/* rotate it around the center of the texture; you can rotate it from a different point, too! */
|
||||
center.x = texture_width / 2.0f;
|
||||
center.y = texture_height / 2.0f;
|
||||
SDL_RenderTextureRotated(renderer, texture, NULL, &dst_rect, rotation, ¢er, SDL_FLIP_NONE);
|
||||
|
||||
/* this next whole thing is _super_ expensive. Seriously, don't do this in real life. */
|
||||
|
||||
/* Download the pixels of what has just been rendered. This has to wait for the GPU to finish rendering it and everything before it,
|
||||
and then make an expensive copy from the GPU to system RAM! */
|
||||
surface = SDL_RenderReadPixels(renderer, NULL);
|
||||
|
||||
/* This is also expensive, but easier: convert the pixels to a format we want. */
|
||||
if (surface && (surface->format != SDL_PIXELFORMAT_RGBA8888) && (surface->format != SDL_PIXELFORMAT_BGRA8888)) {
|
||||
SDL_Surface *converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA8888);
|
||||
SDL_DestroySurface(surface);
|
||||
surface = converted;
|
||||
}
|
||||
|
||||
if (surface) {
|
||||
/* Rebuild converted_texture if the dimensions have changed (window resized, etc). */
|
||||
if ((surface->w != converted_texture_width) || (surface->h != converted_texture_height)) {
|
||||
SDL_DestroyTexture(converted_texture);
|
||||
converted_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, surface->w, surface->h);
|
||||
if (!converted_texture) {
|
||||
SDL_Log("Couldn't (re)create conversion texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
converted_texture_width = surface->w;
|
||||
converted_texture_height = surface->h;
|
||||
}
|
||||
|
||||
/* Turn each pixel into either black or white. This is a lousy technique but it works here.
|
||||
In real life, something like Floyd-Steinberg dithering might work
|
||||
better: https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering*/
|
||||
int x, y;
|
||||
for (y = 0; y < surface->h; y++) {
|
||||
Uint32 *pixels = (Uint32 *) (((Uint8 *) surface->pixels) + (y * surface->pitch));
|
||||
for (x = 0; x < surface->w; x++) {
|
||||
Uint8 *p = (Uint8 *) (&pixels[x]);
|
||||
const Uint32 average = (((Uint32) p[1]) + ((Uint32) p[2]) + ((Uint32) p[3])) / 3;
|
||||
if (average == 0) {
|
||||
p[0] = p[3] = 0xFF; p[1] = p[2] = 0; /* make pure black pixels red. */
|
||||
} else {
|
||||
p[1] = p[2] = p[3] = (average > 50) ? 0xFF : 0x00; /* make everything else either black or white. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* upload the processed pixels back into a texture. */
|
||||
SDL_UpdateTexture(converted_texture, NULL, surface->pixels, surface->pitch);
|
||||
SDL_DestroySurface(surface);
|
||||
|
||||
/* draw the texture to the top-left of the screen. */
|
||||
dst_rect.x = dst_rect.y = 0.0f;
|
||||
dst_rect.w = ((float) WINDOW_WIDTH) / 4.0f;
|
||||
dst_rect.h = ((float) WINDOW_HEIGHT) / 4.0f;
|
||||
SDL_RenderTexture(renderer, converted_texture, NULL, &dst_rect);
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(converted_texture);
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 100 KiB |
@@ -0,0 +1,4 @@
|
||||
This example creates an SDL window and renderer, and draws some text
|
||||
using SDL_RenderDebugText(). This is not quality text rendering, but it can
|
||||
be helpful for simple apps, debugging, or showing something in a pinch.
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws some text
|
||||
* using SDL_RenderDebugText() every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_SetAppMetadata("Example Renderer Debug Texture", "1.0", "com.example.renderer-debug-text");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/debug-text", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
const int charsize = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
|
||||
|
||||
/* as you can see from this, rendering draws over whatever was drawn before it. */
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); /* black, full alpha */
|
||||
SDL_RenderClear(renderer); /* start with a blank canvas. */
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */
|
||||
SDL_RenderDebugText(renderer, 272, 100, "Hello world!");
|
||||
SDL_RenderDebugText(renderer, 224, 150, "This is some debug text.");
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 51, 102, 255, SDL_ALPHA_OPAQUE); /* light blue, full alpha */
|
||||
SDL_RenderDebugText(renderer, 184, 200, "You can do it in different colors.");
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE); /* white, full alpha */
|
||||
|
||||
SDL_SetRenderScale(renderer, 4.0f, 4.0f);
|
||||
SDL_RenderDebugText(renderer, 14, 65, "It can be scaled.");
|
||||
SDL_SetRenderScale(renderer, 1.0f, 1.0f);
|
||||
SDL_RenderDebugText(renderer, 64, 350, "This only does ASCII chars. So this laughing emoji won't draw: 🤣");
|
||||
|
||||
SDL_RenderDebugTextFormat(renderer, (float) ((WINDOW_WIDTH - (charsize * 46)) / 2), 400, "(This program has been running for %" SDL_PRIu64 " seconds.)", SDL_GetTicks() / 1000);
|
||||
|
||||
SDL_RenderPresent(renderer); /* put it all on the screen! */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,3 @@
|
||||
This example creates an SDL window and renderer, and uses
|
||||
SDL_RenderTextureAffine to draw a 3D cube using only 2D rendering operations.
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/* affine-textures.c ... */
|
||||
|
||||
/*
|
||||
* This example creates an SDL window and renderer, and then draws a cube
|
||||
* using affine-transformed textures every frame.
|
||||
*
|
||||
* This code is public domain. Feel free to use it for any purpose!
|
||||
*/
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
/* We will use this renderer to draw into this window every frame. */
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
static int texture_width = 0;
|
||||
static int texture_height = 0;
|
||||
|
||||
#define WINDOW_WIDTH 640
|
||||
#define WINDOW_HEIGHT 480
|
||||
|
||||
/* This function runs once at startup. */
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
char *png_path = NULL;
|
||||
|
||||
SDL_SetAppMetadata("Example Renderer Affine Textures", "1.0", "com.example.renderer-affine-textures");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
if (!SDL_CreateWindowAndRenderer("examples/renderer/affine-textures", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
|
||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
|
||||
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
|
||||
times) with data from a bitmap file. */
|
||||
|
||||
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
|
||||
Load a .png into a surface, move it to a texture from there. */
|
||||
SDL_asprintf(&png_path, "%ssample.png", SDL_GetBasePath()); /* allocate a string of the full file path */
|
||||
surface = SDL_LoadPNG(png_path);
|
||||
if (!surface) {
|
||||
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_free(png_path); /* done with this, the file is loaded. */
|
||||
|
||||
texture_width = surface->w;
|
||||
texture_height = surface->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
|
||||
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_EVENT_QUIT) {
|
||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
||||
}
|
||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
||||
}
|
||||
|
||||
/* This function runs once per frame, and is the heart of the program. */
|
||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
||||
{
|
||||
const float x0 = 0.5f * WINDOW_WIDTH;
|
||||
const float y0 = 0.5f * WINDOW_HEIGHT;
|
||||
const float px = SDL_min(WINDOW_WIDTH, WINDOW_HEIGHT) / SDL_sqrtf(3.0f);
|
||||
|
||||
const Uint64 now = SDL_GetTicks();
|
||||
const float rad = (((float) ((int) (now % 2000))) / 2000.0f) * SDL_PI_F * 2;
|
||||
const float cos = SDL_cosf(rad);
|
||||
const float sin = SDL_sinf(rad);
|
||||
const float k[3] = { 3.0f / SDL_sqrtf(50.0f), 4.0f / SDL_sqrtf(50.0f), 5.0f / SDL_sqrtf(50.0f)};
|
||||
float mat[9] = {
|
||||
cos + (1.0f-cos)*k[0]*k[0], -sin*k[2] + (1.0f-cos)*k[0]*k[1], sin*k[1] + (1.0f-cos)*k[0]*k[2],
|
||||
sin*k[2] + (1.0f-cos)*k[0]*k[1], cos + (1.0f-cos)*k[1]*k[1], -sin*k[0] + (1.0f-cos)*k[1]*k[2],
|
||||
-sin*k[1] + (1.0f-cos)*k[0]*k[2], sin*k[0] + (1.0f-cos)*k[1]*k[2], cos + (1.0f-cos)*k[2]*k[2],
|
||||
};
|
||||
|
||||
float corners[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
const float x = (i & 1) ? -0.5f : 0.5f;
|
||||
const float y = (i & 2) ? -0.5f : 0.5f;
|
||||
const float z = (i & 4) ? -0.5f : 0.5f;
|
||||
corners[0 + 2*i] = mat[0]*x + mat[1]*y + mat[2]*z;
|
||||
corners[1 + 2*i] = mat[3]*x + mat[4]*y + mat[5]*z;
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 0x42, 0x87, 0xf5, SDL_ALPHA_OPAQUE); // light blue background.
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
for (i = 1; i < 7; i++) {
|
||||
const int dir = 3 & ((i & 4) ? ~i : i);
|
||||
const int odd = (i & 1) ^ ((i & 2) >> 1) ^ ((i & 4) >> 2);
|
||||
if (0 < (odd ? 1.0f : -1.0f) * mat[5 + dir]) continue;
|
||||
int origin_index = (1 << ((dir - 1) % 3));
|
||||
int right_index = (1 << ((dir + odd) % 3)) | origin_index;
|
||||
int down_index = (1 << ((dir + (odd^1)) % 3)) | origin_index;
|
||||
if (!odd) {
|
||||
origin_index ^= 7;
|
||||
right_index ^= 7;
|
||||
down_index ^= 7;
|
||||
}
|
||||
SDL_FPoint origin, right, down;
|
||||
origin.x = x0 + px*corners[0 + 2*origin_index];
|
||||
origin.y = y0 + px*corners[1 + 2*origin_index];
|
||||
right.x = x0 + px*corners[0 + 2*right_index];
|
||||
right.y = y0 + px*corners[1 + 2*right_index];
|
||||
down.x = x0 + px*corners[0 + 2*down_index];
|
||||
down.y = y0 + px*corners[1 + 2*down_index];
|
||||
SDL_RenderTextureAffine(renderer, texture, NULL, &origin, &right, &down);
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
/* This function runs once at shutdown. */
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
||||
{
|
||||
SDL_DestroyTexture(texture);
|
||||
/* SDL will clean up the window/renderer for us. */
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 229 KiB |