CoreNative - Basic Query Building Done!


We have some queries, we can create them, assign a render callback, and generate something to draw with.

Lo and behold: the almighty black rectangle.


Genuinely, doesn't it look beautiful?

Actually, I think code looks more interesting than the rectangle, so let me tell you how we get to render it.

void render_rectangle(TAG_QueryReference* ref) {
    DrawRectangle(ref->position.x, ref->position.y, ref->size.x, ref->size.y, BLACK);
}
void init_app(TAG_App* app) {
    TAG_Query* rectangle = TAG_Query_init(ARENA_PERMANENT);
    rectangle->render = render_rectangle;
    int queryRectangle = TAG_GraphicsContext_add_query(app->graphics_context, rectangle);
    int rectResult;
    TAG_QueryReference* refRect = TAG_GraphicsContext_add_to_draw(app->graphics_context, queryRectangle, &rectResult);
    refRect->position = INIT_STRUCT(Vector2, 100, 50);
    refRect->size = INIT_STRUCT(Vector2, 200, 200);
}
void update_app(TAG_UpdateContext* utx) {
}
void render_app(TAG_GraphicsContext* gtx) {
    TAG_GraphicsContext_begin(gtx);
    TAG_GraphicsContext_draw_queries(gtx);
}
int main(void) {
  TAG_App app = TAG_App_init("Test Game App", 1920, 1080, 60);
  set_current_app(&app);
  app.graphics_context = TAG_GraphicsContext_init();
  app.init = init_app;
  app.render = render_app;
  app.update = update_app;
  if (!app.is_initialized) {
    printf("Failed to initialize application\n");
    return 1;
  }
  // Run the application
  TAG_App_run(&app);
  TAG_App_destroy(&app);
  return 0;
}

The code above tells us what we can do with the new Twinspire CoreNative, so let's discuss what's happening.

The flow is pretty simple:

  • We initialise the application and bootstrap much quicker than we did in Twinspire Core.
  • Set the application as globally accessible. This is essential for memory arena allocations.
  • Allocate our graphics context (no update context yet).
  • Setup some application callbacks.
  • A bit redundant, but check if the application is initialised.
  • Then set to run the application.

Pretty simple.

The more interesting stuff comes in the initialisation process. So, what are we doing?

  • We create a query into permanent storage. This lives for the entire applications' lifecycle.
  • We tell that query to store a pointer to a function we want to render with. We can optionally assign user_data, which can be any sized structure we assign it.
  • However, the query simply defines what type of thing we want to draw, we haven't actually "added" it to the graphics context. This is where the next few lines come in, adding that query to drawing, and we can have as many as we want.

If I wrote a loop to add more of the same query, this is fairly straightforward and gives us exactly what we expect:

I simply just adjusted the code like so:

TAG_Query* rectangle = TAG_Query_init(ARENA_PERMANENT);
rectangle->render = render_rectangle;
int queryRectangle = TAG_GraphicsContext_add_query(app->graphics_context, rectangle);
for (int i = 0; i < 5; i++) {
    int rectResult;
    TAG_QueryReference* refRect = TAG_GraphicsContext_add_to_draw(app->graphics_context, queryRectangle, &rectResult);
    refRect->position = INIT_STRUCT(Vector2, 100, (float)(i * 50 + 53));
    refRect->size = INIT_STRUCT(Vector2, 50, 40);
}

Nothing too complicated, but serves the purpose we expect. So, what you can see is the barebones of CoreNative, but given time, more interesting stuff later.

Read the Announcement Post for what Twinspire CoreNative is.

Leave a comment

Log in with itch.io to leave a comment.