Rudimentary resolution changer, window icon
This commit is contained in:
parent
aeeef1a60f
commit
eb4b0e1714
@ -305,35 +305,47 @@ Texture *asset_texLoadImage(AssetManager *assetManager, MemoryArena_ *arena,
|
|||||||
{
|
{
|
||||||
/* Open the texture image */
|
/* Open the texture image */
|
||||||
i32 imgWidth, imgHeight, bytesPerPixel;
|
i32 imgWidth, imgHeight, bytesPerPixel;
|
||||||
stbi_set_flip_vertically_on_load(TRUE);
|
|
||||||
u8 *image =
|
u8 *image =
|
||||||
stbi_load(path, &imgWidth, &imgHeight, &bytesPerPixel, 0);
|
asset_imageLoad(&imgWidth, &imgHeight, &bytesPerPixel, path, TRUE);
|
||||||
|
|
||||||
#ifdef DENGINE_DEBUG
|
Texture *result = NULL;
|
||||||
if (imgWidth != imgHeight)
|
if (image)
|
||||||
{
|
{
|
||||||
printf(
|
result = asset_texGetFreeSlot(assetManager, arena, key);
|
||||||
"asset_texLoadImage() warning: Sprite sheet is not square: "
|
|
||||||
"%dx%dpx\n", imgWidth, imgHeight);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!image)
|
|
||||||
{
|
|
||||||
printf("stdbi_load() failed: %s\n", stbi_failure_reason());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture *result = asset_texGetFreeSlot(assetManager, arena, key);
|
|
||||||
*result = textureGen(CAST(GLuint)(imgWidth), CAST(GLuint)(imgHeight),
|
*result = textureGen(CAST(GLuint)(imgWidth), CAST(GLuint)(imgHeight),
|
||||||
CAST(GLint)(bytesPerPixel), image);
|
CAST(GLint)(bytesPerPixel), image);
|
||||||
|
|
||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
stbi_image_free(image);
|
asset_imageFree(image);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 *asset_imageLoad(i32 *width, i32 *height, i32 *bpp, const char *const path,
|
||||||
|
b32 flipVertically)
|
||||||
|
{
|
||||||
|
stbi_set_flip_vertically_on_load(flipVertically);
|
||||||
|
u8 *image = stbi_load(path, width, height, bpp, 0);
|
||||||
|
|
||||||
|
if (*width != *height)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"asset_texLoadImage() warning: Sprite sheet is not square: "
|
||||||
|
"%dx%dpx\n",
|
||||||
|
*width, *height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image)
|
||||||
|
{
|
||||||
|
printf("stdbi_load() failed: %s\n", stbi_failure_reason());
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
void asset_imageFree(u8 *image) { stbi_image_free(image); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*********************************
|
*********************************
|
||||||
* Animation Asset Managing
|
* Animation Asset Managing
|
||||||
|
135
src/Asteroid.c
135
src/Asteroid.c
@ -340,17 +340,17 @@ INTERNAL void addAsteroidWithSpec(GameWorldState *world,
|
|||||||
i32 randValue = rand();
|
i32 randValue = rand();
|
||||||
if (!spec)
|
if (!spec)
|
||||||
{
|
{
|
||||||
i32 randX = (randValue % (i32)world->worldSize.w);
|
i32 randX = (randValue % (i32)world->size.w);
|
||||||
i32 randY = (randValue % (i32)world->worldSize.h);
|
i32 randY = (randValue % (i32)world->size.h);
|
||||||
|
|
||||||
v2 midpoint = v2_scale(world->worldSize, 0.5f);
|
v2 midpoint = v2_scale(world->size, 0.5f);
|
||||||
|
|
||||||
Rect topLeftQuadrant = {V2(0, midpoint.y),
|
Rect topLeftQuadrant = {V2(0, midpoint.y),
|
||||||
V2(midpoint.x, world->worldSize.y)};
|
V2(midpoint.x, world->size.y)};
|
||||||
Rect botLeftQuadrant = {V2(0, 0), midpoint};
|
Rect botLeftQuadrant = {V2(0, 0), midpoint};
|
||||||
Rect topRightQuadrant = {midpoint, world->worldSize};
|
Rect topRightQuadrant = {midpoint, world->size};
|
||||||
Rect botRightQuadrant = {V2(midpoint.x, 0),
|
Rect botRightQuadrant = {V2(midpoint.x, 0),
|
||||||
V2(world->worldSize.x, midpoint.y)};
|
V2(world->size.x, midpoint.y)};
|
||||||
|
|
||||||
// NOTE(doyle): Off-screen so asteroids "float" into view. There's no
|
// NOTE(doyle): Off-screen so asteroids "float" into view. There's no
|
||||||
// particular order, just pushing things offscreen when they get
|
// particular order, just pushing things offscreen when they get
|
||||||
@ -579,7 +579,7 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
|
|||||||
|
|
||||||
world->camera.min = V2(0, 0);
|
world->camera.min = V2(0, 0);
|
||||||
world->camera.max = state->renderer.size;
|
world->camera.max = state->renderer.size;
|
||||||
world->worldSize = state->renderer.size;
|
world->size = state->renderer.size;
|
||||||
|
|
||||||
{ // Init null entity
|
{ // Init null entity
|
||||||
Entity *nullEntity = &world->entityList[world->entityIndex++];
|
Entity *nullEntity = &world->entityList[world->entityIndex++];
|
||||||
@ -617,8 +617,8 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
|
|||||||
|
|
||||||
for (i32 i = 0; i < world->numStarP; i++)
|
for (i32 i = 0; i < world->numStarP; i++)
|
||||||
{
|
{
|
||||||
i32 randX = rand() % (i32)world->worldSize.x;
|
i32 randX = rand() % (i32)world->size.x;
|
||||||
i32 randY = rand() % (i32)world->worldSize.y;
|
i32 randY = rand() % (i32)world->size.y;
|
||||||
|
|
||||||
world->starPList[i] = V2i(randX, randY);
|
world->starPList[i] = V2i(randX, randY);
|
||||||
}
|
}
|
||||||
@ -821,15 +821,15 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Loop entity around world */
|
/* Loop entity around world */
|
||||||
if (entity->pos.y >= world->worldSize.h)
|
if (entity->pos.y >= world->size.h)
|
||||||
entity->pos.y = 0;
|
entity->pos.y = 0;
|
||||||
else if (entity->pos.y < 0)
|
else if (entity->pos.y < 0)
|
||||||
entity->pos.y = world->worldSize.h;
|
entity->pos.y = world->size.h;
|
||||||
|
|
||||||
if (entity->pos.x >= world->worldSize.w)
|
if (entity->pos.x >= world->size.w)
|
||||||
entity->pos.x = 0;
|
entity->pos.x = 0;
|
||||||
else if (entity->pos.x < 0)
|
else if (entity->pos.x < 0)
|
||||||
entity->pos.x = world->worldSize.w;
|
entity->pos.x = world->size.w;
|
||||||
|
|
||||||
i32 collisionIndex = moveEntity(world, &state->transientArena, entity,
|
i32 collisionIndex = moveEntity(world, &state->transientArena, entity,
|
||||||
i, ddP, dt, ddPSpeedInMs);
|
i, ddP, dt, ddPSpeedInMs);
|
||||||
@ -1007,57 +1007,104 @@ INTERNAL void startMenuUpdate(GameState *state, Memory *memory, f32 dt)
|
|||||||
|
|
||||||
v2 screenCenter = v2_scale(renderer->size, 0.5f);
|
v2 screenCenter = v2_scale(renderer->size, 0.5f);
|
||||||
|
|
||||||
const char *const title = "Asteroids";
|
|
||||||
v2 titleDim = asset_fontStringDimInPixels(arial25, title);
|
|
||||||
v2 halfTitleDim = v2_scale(titleDim, 0.5f);
|
|
||||||
v2 titleP = v2_add(screenCenter, V2(0, 40));
|
|
||||||
titleP = v2_sub(titleP, halfTitleDim);
|
|
||||||
|
|
||||||
renderer_stringFixed(renderer, transientArena, arial25, title, titleP,
|
|
||||||
V2(0, 0), 0, V4(1, 0, 0, 1), 0);
|
|
||||||
|
|
||||||
ui_beginState(uiState);
|
ui_beginState(uiState);
|
||||||
|
|
||||||
{ // Draw blinking Start Game prompt
|
if (menuState->optionsShow)
|
||||||
menuState->startMenuGameStartBlinkTimer -= dt;
|
|
||||||
if (menuState->startMenuGameStartBlinkTimer < 0.0f)
|
|
||||||
{
|
{
|
||||||
menuState->startMenuGameStartBlinkTimer = 1.0f;
|
if (platform_queryKey(&inputBuffer->keys[keycode_o],
|
||||||
menuState->startMenuToggleShow =
|
readkeytype_one_shot, KEY_DELAY_NONE) ||
|
||||||
(menuState->startMenuToggleShow) ? FALSE : TRUE;
|
platform_queryKey(&inputBuffer->keys[keycode_backspace],
|
||||||
|
readkeytype_one_shot, KEY_DELAY_NONE))
|
||||||
|
{
|
||||||
|
menuState->optionsShow = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f32 textYOffset = arial25->size * 1.5f;;
|
||||||
|
const char *const title = "Options";
|
||||||
|
v2 p = v2_add(screenCenter, V2(0, textYOffset));
|
||||||
|
renderer_stringFixedCentered(renderer, transientArena, arial25,
|
||||||
|
title, p, V2(0, 0), 0, V4(1, 0, 1, 1),
|
||||||
|
0);
|
||||||
|
|
||||||
|
const char *const resolutionLabel = "Resolution";
|
||||||
|
p = v2_add(screenCenter, V2(0, 0));
|
||||||
|
|
||||||
|
renderer_stringFixedCentered(renderer, transientArena, arial25,
|
||||||
|
resolutionLabel, p, V2(0, 0), 0,
|
||||||
|
V4(1, 0, 1, 1), 0);
|
||||||
|
|
||||||
|
const char *const resSizeLabel = "< 800x600 >";
|
||||||
|
p = v2_add(screenCenter, V2(0, -textYOffset));
|
||||||
|
|
||||||
|
renderer_stringFixedCentered(renderer, transientArena, arial25,
|
||||||
|
resSizeLabel, p, V2(0, 0), 0,
|
||||||
|
V4(1, 0, 1, 1), 0);
|
||||||
|
|
||||||
|
if (platform_queryKey(&inputBuffer->keys[keycode_enter],
|
||||||
|
readkeytype_one_shot, KEY_DELAY_NONE))
|
||||||
|
{
|
||||||
|
menuState->newResolutionRequest = TRUE;
|
||||||
|
menuState->newResolution = V2(800, 600);
|
||||||
|
|
||||||
|
renderer->size = menuState->newResolution;
|
||||||
|
|
||||||
|
GameWorldState *world = GET_STATE_DATA(
|
||||||
|
state, &state->persistentArena, GameWorldState);
|
||||||
|
world->size = menuState->newResolution;
|
||||||
|
world->camera.max = menuState->newResolution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Draw title text */
|
||||||
|
const char *const title = "Asteroids";
|
||||||
|
v2 p = v2_add(screenCenter, V2(0, 40));
|
||||||
|
renderer_stringFixedCentered(renderer, transientArena, arial25, title,
|
||||||
|
p, V2(0, 0), 0, V4(1, 0, 0, 1), 0);
|
||||||
|
|
||||||
|
/* Draw blinking start game prompt */
|
||||||
|
menuState->startPromptBlinkTimer -= dt;
|
||||||
|
if (menuState->startPromptBlinkTimer < 0.0f)
|
||||||
|
{
|
||||||
|
menuState->startPromptBlinkTimer = 1.0f;
|
||||||
|
menuState->startPromptShow =
|
||||||
|
(menuState->startPromptShow) ? FALSE : TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menuState->startMenuToggleShow)
|
if (menuState->startPromptShow)
|
||||||
{
|
{
|
||||||
const char *const gameStart = "Press enter to start";
|
const char *const gameStart = "Press enter to start";
|
||||||
v2 gameStartDim = asset_fontStringDimInPixels(arial25, gameStart);
|
v2 p = v2_add(screenCenter, V2(0, -40));
|
||||||
v2 halfGameStartDim = v2_scale(gameStartDim, 0.5f);
|
renderer_stringFixedCentered(renderer, transientArena, arial25,
|
||||||
v2 gameStartP = v2_add(screenCenter, V2(0, -40));
|
gameStart, p, V2(0, 0), 0,
|
||||||
gameStartP = v2_sub(gameStartP, halfGameStartDim);
|
V4(1, 1, 0, 1), 0);
|
||||||
|
|
||||||
renderer_stringFixed(renderer, transientArena, arial25, gameStart,
|
|
||||||
gameStartP, V2(0, 0), 0, V4(1, 1, 0, 1), 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{ // Draw show options prompt
|
||||||
const char *const optionPrompt = "Press [o] for options ";
|
const char *const optionPrompt = "Press [o] for options ";
|
||||||
v2 dim = asset_fontStringDimInPixels(arial25, optionPrompt);
|
|
||||||
v2 halfDim = v2_scale(dim, 0.5f);
|
|
||||||
v2 p = v2_add(screenCenter, V2(0, -120));
|
v2 p = v2_add(screenCenter, V2(0, -120));
|
||||||
p = v2_sub(p, halfDim);
|
renderer_stringFixedCentered(renderer, transientArena, arial25,
|
||||||
renderer_stringFixed(renderer, transientArena, arial25, optionPrompt, p,
|
optionPrompt, p, V2(0, 0), 0, V4(1, 1, 0, 1),
|
||||||
V2(0, 0), 0, V4(1, 1, 0, 1), 0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform_queryKey(&inputBuffer->keys[keycode_enter],
|
if (platform_queryKey(&inputBuffer->keys[keycode_enter],
|
||||||
readkeytype_one_shot, KEY_DELAY_NONE))
|
readkeytype_one_shot, KEY_DELAY_NONE))
|
||||||
{
|
{
|
||||||
state->currState = appstate_GameWorldState;
|
|
||||||
|
|
||||||
GameWorldState *world =
|
GameWorldState *world =
|
||||||
GET_STATE_DATA(state, &state->persistentArena, GameWorldState);
|
GET_STATE_DATA(state, &state->persistentArena, GameWorldState);
|
||||||
addPlayer(world);
|
addPlayer(world);
|
||||||
|
|
||||||
|
state->currState = appstate_GameWorldState;
|
||||||
|
}
|
||||||
|
else if (platform_queryKey(&inputBuffer->keys[keycode_o],
|
||||||
|
readkeytype_one_shot, KEY_DELAY_NONE))
|
||||||
|
{
|
||||||
|
menuState->optionsShow = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_endState(uiState, inputBuffer);
|
ui_endState(uiState, inputBuffer);
|
||||||
|
@ -97,6 +97,14 @@ INTERNAL void scrollCallback(GLFWwindow *window, double xOffset, double yOffset)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL void setGlfwWindowHints()
|
||||||
|
{
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
i32 main(void)
|
i32 main(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -105,10 +113,7 @@ i32 main(void)
|
|||||||
**************************
|
**************************
|
||||||
*/
|
*/
|
||||||
glfwInit();
|
glfwInit();
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
setGlfwWindowHints();
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
|
||||||
|
|
||||||
i32 windowWidth = 1600;
|
i32 windowWidth = 1600;
|
||||||
i32 windowHeight = 900;
|
i32 windowHeight = 900;
|
||||||
@ -181,6 +186,19 @@ i32 main(void)
|
|||||||
|
|
||||||
glfwSetWindowUserPointer(window, CAST(void *)(gameState));
|
glfwSetWindowUserPointer(window, CAST(void *)(gameState));
|
||||||
|
|
||||||
|
{
|
||||||
|
i32 width, height;
|
||||||
|
char *iconPath = "data/textures/Asteroids/icon.png";
|
||||||
|
u8 *pixels = asset_imageLoad(&width, &height, NULL, iconPath, FALSE);
|
||||||
|
|
||||||
|
if (pixels)
|
||||||
|
{
|
||||||
|
GLFWimage image = {width, height, pixels};
|
||||||
|
glfwSetWindowIcon(window, 1, &image);
|
||||||
|
asset_imageFree(pixels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*******************
|
*******************
|
||||||
* GAME LOOP
|
* GAME LOOP
|
||||||
@ -252,6 +270,19 @@ i32 main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
startTime = endTime;
|
startTime = endTime;
|
||||||
|
|
||||||
|
StartMenuState *menuState =
|
||||||
|
ASTEROID_GET_STATE_DATA(gameState, StartMenuState);
|
||||||
|
if (menuState)
|
||||||
|
{
|
||||||
|
if (menuState->newResolutionRequest)
|
||||||
|
{
|
||||||
|
windowSize = menuState->newResolution;
|
||||||
|
glfwSetWindowSize(window, (i32)windowSize.w, (i32)windowSize.h);
|
||||||
|
|
||||||
|
menuState->newResolutionRequest = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
@ -41,9 +41,14 @@ TexAtlas *asset_atlasGet(AssetManager *const assetManager,
|
|||||||
const char *const key);
|
const char *const key);
|
||||||
Texture *asset_texGetFreeSlot(AssetManager *const assetManager,
|
Texture *asset_texGetFreeSlot(AssetManager *const assetManager,
|
||||||
MemoryArena_ *const arena, const char *const key);
|
MemoryArena_ *const arena, const char *const key);
|
||||||
Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena_ *arena,
|
Texture *asset_texLoadImage(AssetManager *assetManager, MemoryArena_ *arena,
|
||||||
const char *const path, const char *const key);
|
const char *const path, const char *const key);
|
||||||
|
|
||||||
|
u8 *asset_imageLoad(i32 *width, i32 *height, i32 *bpp, const char *const path,
|
||||||
|
b32 flipVertically);
|
||||||
|
|
||||||
|
void asset_imageFree(u8 *image);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*********************************
|
*********************************
|
||||||
* Animation Asset Managing
|
* Animation Asset Managing
|
||||||
|
@ -45,8 +45,8 @@ typedef struct GameWorldState
|
|||||||
i32 numAudioRenderers;
|
i32 numAudioRenderers;
|
||||||
|
|
||||||
f32 pixelsPerMeter;
|
f32 pixelsPerMeter;
|
||||||
v2 worldSize;
|
|
||||||
Rect camera;
|
Rect camera;
|
||||||
|
v2 size;
|
||||||
|
|
||||||
// TODO(doyle): Ensure we change this if it gets too big
|
// TODO(doyle): Ensure we change this if it gets too big
|
||||||
b32 collisionTable[entitytype_count][entitytype_count];
|
b32 collisionTable[entitytype_count][entitytype_count];
|
||||||
@ -54,8 +54,13 @@ typedef struct GameWorldState
|
|||||||
|
|
||||||
typedef struct StartMenuState
|
typedef struct StartMenuState
|
||||||
{
|
{
|
||||||
f32 startMenuGameStartBlinkTimer;
|
f32 startPromptBlinkTimer;
|
||||||
b32 startMenuToggleShow;
|
b32 startPromptShow;
|
||||||
|
|
||||||
|
b32 optionsShow;
|
||||||
|
|
||||||
|
b32 newResolutionRequest;
|
||||||
|
v2 newResolution;
|
||||||
} StartMenuState;
|
} StartMenuState;
|
||||||
|
|
||||||
typedef struct GameState
|
typedef struct GameState
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
|
|
||||||
#include "Dengine/Common.h"
|
#include "Dengine/Common.h"
|
||||||
#include "Dengine/Math.h"
|
#include "Dengine/Math.h"
|
||||||
#include "Dengine/Assets.h"
|
#include "Dengine/AssetManager.h"
|
||||||
|
|
||||||
/* Forward Declaration */
|
/* Forward Declaration */
|
||||||
typedef struct AssetManager AssetManager;
|
|
||||||
typedef struct Font Font;
|
typedef struct Font Font;
|
||||||
typedef struct Entity Entity;
|
typedef struct Entity Entity;
|
||||||
typedef struct MemoryArena MemoryArena_;
|
typedef struct MemoryArena MemoryArena_;
|
||||||
@ -125,6 +124,22 @@ inline void renderer_stringFixed(Renderer *const renderer, MemoryArena_ *arena,
|
|||||||
pivotPoint, rotate, color, flags);
|
pivotPoint, rotate, color, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void renderer_stringFixedCentered(Renderer *const renderer,
|
||||||
|
MemoryArena_ *arena, Font *const font,
|
||||||
|
const char *const string, v2 pos,
|
||||||
|
v2 pivotPoint, Radians rotate,
|
||||||
|
v4 color, RenderFlags flags)
|
||||||
|
{
|
||||||
|
Rect staticCamera = {V2(0, 0), renderer->size};
|
||||||
|
|
||||||
|
v2 dim = asset_fontStringDimInPixels(font, string);
|
||||||
|
v2 halfDim = v2_scale(dim, 0.5f);
|
||||||
|
pos = v2_sub(pos, halfDim);
|
||||||
|
|
||||||
|
renderer_string(renderer, arena, staticCamera, font, string, pos,
|
||||||
|
pivotPoint, rotate, color, flags);
|
||||||
|
}
|
||||||
|
|
||||||
void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena,
|
void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena,
|
||||||
Rect camera, Entity *entity, v2 pivotPoint, Degrees rotate,
|
Rect camera, Entity *entity, v2 pivotPoint, Degrees rotate,
|
||||||
v4 color, RenderFlags flags);
|
v4 color, RenderFlags flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user