Merge branch 'master' into big-cmake-changes
This commit is contained in:
commit
7b199c3145
|
|
@ -38,6 +38,7 @@ option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pr
|
||||||
option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF)
|
option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF)
|
||||||
option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF)
|
option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF)
|
||||||
option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF)
|
option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF)
|
||||||
|
option(SUPPORT_DATA_STORAGE "Support for persistent data storage" ON)
|
||||||
|
|
||||||
# rlgl.h
|
# rlgl.h
|
||||||
option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON)
|
option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
#cmakedefine SUPPORT_HIGH_DPI 1
|
#cmakedefine SUPPORT_HIGH_DPI 1
|
||||||
// Support CompressData() and DecompressData() functions
|
// Support CompressData() and DecompressData() functions
|
||||||
#cmakedefine SUPPORT_COMPRESSION_API 1
|
#cmakedefine SUPPORT_COMPRESSION_API 1
|
||||||
|
// Support for persistent data storage
|
||||||
|
#cmakedefine SUPPORT_DATA_STORAGE 1
|
||||||
|
|
||||||
// rlgl.h
|
// rlgl.h
|
||||||
// Support VR simulation functionality (stereo rendering)
|
// Support VR simulation functionality (stereo rendering)
|
||||||
|
|
|
||||||
148
src/core.c
148
src/core.c
|
|
@ -333,12 +333,6 @@ typedef struct {
|
||||||
bool isKeyboard; // True if device has letter keycodes
|
bool isKeyboard; // True if device has letter keycodes
|
||||||
bool isGamepad; // True if device has gamepad buttons
|
bool isGamepad; // True if device has gamepad buttons
|
||||||
} InputEventWorker;
|
} InputEventWorker;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int contents[8]; // Key events FIFO contents (8 positions)
|
|
||||||
char head; // Key events FIFO head position
|
|
||||||
char tail; // Key events FIFO tail position
|
|
||||||
} KeyEventFifo;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct { int x; int y; } Point;
|
typedef struct { int x; int y; } Point;
|
||||||
|
|
@ -420,7 +414,7 @@ typedef struct CoreData {
|
||||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
||||||
int defaultMode; // Default keyboard mode
|
int defaultMode; // Default keyboard mode
|
||||||
struct termios defaultSettings; // Default keyboard settings
|
struct termios defaultSettings; // Default keyboard settings
|
||||||
KeyEventFifo lastKeyPressed; // Buffer for holding keydown events as they arrive (Needed due to multitreading of event workers)
|
int fd; // File descriptor for the evdev keyboard
|
||||||
#endif
|
#endif
|
||||||
} Keyboard;
|
} Keyboard;
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -559,7 +553,8 @@ static void RestoreTerminal(void); // Restore terminal
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void InitEvdevInput(void); // Evdev inputs initialization
|
static void InitEvdevInput(void); // Evdev inputs initialization
|
||||||
static void EventThreadSpawn(char *device); // Identifies a input device and spawns a thread to handle it if needed
|
static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
|
||||||
|
static void PollKeyboardEvents(void); // Process evdev keyboard events.
|
||||||
static void *EventThread(void *arg); // Input device events reading thread
|
static void *EventThread(void *arg); // Input device events reading thread
|
||||||
|
|
||||||
static void InitGamepad(void); // Init raw gamepad input
|
static void InitGamepad(void); // Init raw gamepad input
|
||||||
|
|
@ -899,6 +894,13 @@ void CloseWindow(void)
|
||||||
|
|
||||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||||
|
|
||||||
|
// Close the evdev keyboard
|
||||||
|
if (CORE.Input.Keyboard.fd != -1)
|
||||||
|
{
|
||||||
|
close(CORE.Input.Keyboard.fd);
|
||||||
|
CORE.Input.Keyboard.fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||||
{
|
{
|
||||||
if (CORE.Input.eventWorker[i].threadId)
|
if (CORE.Input.eventWorker[i].threadId)
|
||||||
|
|
@ -907,6 +909,7 @@ void CloseWindow(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
|
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -4275,14 +4278,7 @@ static void PollInputEvents(void)
|
||||||
// Register previous keys states
|
// Register previous keys states
|
||||||
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
|
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
|
||||||
|
|
||||||
// Grab a keypress from the evdev fifo if avalable
|
PollKeyboardEvents();
|
||||||
if (CORE.Input.Keyboard.lastKeyPressed.head != CORE.Input.Keyboard.lastKeyPressed.tail)
|
|
||||||
{
|
|
||||||
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = CORE.Input.Keyboard.lastKeyPressed.contents[CORE.Input.Keyboard.lastKeyPressed.tail]; // Read the key from the buffer
|
|
||||||
CORE.Input.Keyboard.keyPressedQueueCount++;
|
|
||||||
|
|
||||||
CORE.Input.Keyboard.lastKeyPressed.tail = (CORE.Input.Keyboard.lastKeyPressed.tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register previous mouse states
|
// Register previous mouse states
|
||||||
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
|
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
|
||||||
|
|
@ -5353,6 +5349,9 @@ static void InitEvdevInput(void)
|
||||||
DIR *directory;
|
DIR *directory;
|
||||||
struct dirent *entity;
|
struct dirent *entity;
|
||||||
|
|
||||||
|
// Initialise keyboard file descriptor
|
||||||
|
CORE.Input.Keyboard.fd = -1;
|
||||||
|
|
||||||
// Reset variables
|
// Reset variables
|
||||||
for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
|
for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -5360,10 +5359,6 @@ static void InitEvdevInput(void)
|
||||||
CORE.Input.Touch.position[i].y = -1;
|
CORE.Input.Touch.position[i].y = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset keypress buffer
|
|
||||||
CORE.Input.Keyboard.lastKeyPressed.head = 0;
|
|
||||||
CORE.Input.Keyboard.lastKeyPressed.tail = 0;
|
|
||||||
|
|
||||||
// Reset keyboard key state
|
// Reset keyboard key state
|
||||||
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
|
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
|
||||||
|
|
||||||
|
|
@ -5377,7 +5372,7 @@ static void InitEvdevInput(void)
|
||||||
if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*"
|
if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*"
|
||||||
{
|
{
|
||||||
sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
|
sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
|
||||||
EventThreadSpawn(path); // Identify the device and spawn a thread for it
|
ConfigureEvdevDevice(path); // Configure the device if appropriate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5386,8 +5381,8 @@ static void InitEvdevInput(void)
|
||||||
else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);
|
else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identifies a input device and spawns a thread to handle it if needed
|
// Identifies a input device and configures it for use if appropriate
|
||||||
static void EventThreadSpawn(char *device)
|
static void ConfigureEvdevDevice(char *device)
|
||||||
{
|
{
|
||||||
#define BITS_PER_LONG (8*sizeof(long))
|
#define BITS_PER_LONG (8*sizeof(long))
|
||||||
#define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)
|
#define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)
|
||||||
|
|
@ -5459,7 +5454,7 @@ static void EventThreadSpawn(char *device)
|
||||||
|
|
||||||
// Identify the device
|
// Identify the device
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the avalable device properties
|
ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the available device properties
|
||||||
|
|
||||||
// Check for absolute input devices
|
// Check for absolute input devices
|
||||||
if (TEST_BIT(evBits, EV_ABS))
|
if (TEST_BIT(evBits, EV_ABS))
|
||||||
|
|
@ -5535,15 +5530,22 @@ static void EventThreadSpawn(char *device)
|
||||||
|
|
||||||
// Decide what to do with the device
|
// Decide what to do with the device
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
if (worker->isTouch || worker->isMouse || worker->isKeyboard)
|
if (worker->isKeyboard && CORE.Input.Keyboard.fd == -1)
|
||||||
|
{
|
||||||
|
// Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a
|
||||||
|
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
|
||||||
|
// threads so that they don't drop events when the frame rate is slow.
|
||||||
|
TRACELOG(LOG_INFO, "RPI: Opening keyboard device: %s", device);
|
||||||
|
CORE.Input.Keyboard.fd = worker->fd;
|
||||||
|
}
|
||||||
|
else if (worker->isTouch || worker->isMouse)
|
||||||
{
|
{
|
||||||
// Looks like an interesting device
|
// Looks like an interesting device
|
||||||
TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s%s)", device,
|
TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s)", device,
|
||||||
worker->isMouse? "mouse " : "",
|
worker->isMouse? "mouse " : "",
|
||||||
worker->isMultitouch? "multitouch " : "",
|
worker->isMultitouch? "multitouch " : "",
|
||||||
worker->isTouch? "touchscreen " : "",
|
worker->isTouch? "touchscreen " : "",
|
||||||
worker->isGamepad? "gamepad " : "",
|
worker->isGamepad? "gamepad " : "");
|
||||||
worker->isKeyboard? "keyboard " : "");
|
|
||||||
|
|
||||||
// Create a thread for this device
|
// Create a thread for this device
|
||||||
int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
|
int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
|
||||||
|
|
@ -5563,7 +5565,7 @@ static void EventThreadSpawn(char *device)
|
||||||
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
|
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find toucnscreens with lower indexes
|
// Find touchscreens with lower indexes
|
||||||
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||||
{
|
{
|
||||||
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
|
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
|
||||||
|
|
@ -5582,8 +5584,7 @@ static void EventThreadSpawn(char *device)
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input device events reading thread
|
static void PollKeyboardEvents(void)
|
||||||
static void *EventThread(void *arg)
|
|
||||||
{
|
{
|
||||||
// Scancode to keycode mapping for US keyboards
|
// Scancode to keycode mapping for US keyboards
|
||||||
// TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard:
|
// TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard:
|
||||||
|
|
@ -5605,12 +5606,62 @@ static void *EventThread(void *arg)
|
||||||
227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,
|
227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,
|
||||||
243,244,245,246,247,248,0,0,0,0,0,0,0, };
|
243,244,245,246,247,248,0,0,0,0,0,0,0, };
|
||||||
|
|
||||||
|
int fd = CORE.Input.Keyboard.fd;
|
||||||
|
if (fd == -1) return;
|
||||||
|
|
||||||
|
struct input_event event;
|
||||||
|
int keycode;
|
||||||
|
|
||||||
|
// Try to read data from the keyboard and only continue if successful
|
||||||
|
while (read(fd, &event, sizeof(event)) == (int)sizeof(event))
|
||||||
|
{
|
||||||
|
// Button parsing
|
||||||
|
if (event.type == EV_KEY)
|
||||||
|
{
|
||||||
|
// Keyboard button parsing
|
||||||
|
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
|
||||||
|
{
|
||||||
|
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
|
||||||
|
|
||||||
|
// Make sure we got a valid keycode
|
||||||
|
if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
|
||||||
|
{
|
||||||
|
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
|
||||||
|
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
|
||||||
|
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
|
||||||
|
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
|
||||||
|
if (event.value >= 1)
|
||||||
|
{
|
||||||
|
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
|
||||||
|
CORE.Input.Keyboard.keyPressedQueueCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||||
|
// Check screen capture key (raylib key: KEY_F12)
|
||||||
|
if (CORE.Input.Keyboard.currentKeyState[301] == 1)
|
||||||
|
{
|
||||||
|
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
||||||
|
screenshotCounter++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
|
||||||
|
|
||||||
|
TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input device events reading thread
|
||||||
|
static void *EventThread(void *arg)
|
||||||
|
{
|
||||||
struct input_event event;
|
struct input_event event;
|
||||||
InputEventWorker *worker = (InputEventWorker *)arg;
|
InputEventWorker *worker = (InputEventWorker *)arg;
|
||||||
|
|
||||||
int touchAction = -1;
|
int touchAction = -1;
|
||||||
bool gestureUpdate = false;
|
bool gestureUpdate = false;
|
||||||
int keycode;
|
|
||||||
|
|
||||||
while (!CORE.Window.shouldClose)
|
while (!CORE.Window.shouldClose)
|
||||||
{
|
{
|
||||||
|
|
@ -5710,39 +5761,6 @@ static void *EventThread(void *arg)
|
||||||
|
|
||||||
if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
|
if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
|
||||||
if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
|
if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
|
||||||
|
|
||||||
// Keyboard button parsing
|
|
||||||
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
|
|
||||||
{
|
|
||||||
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
|
|
||||||
|
|
||||||
// Make sure we got a valid keycode
|
|
||||||
if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
|
|
||||||
{
|
|
||||||
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
|
|
||||||
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
|
|
||||||
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
|
|
||||||
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
|
|
||||||
if (event.value >= 1)
|
|
||||||
{
|
|
||||||
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
|
|
||||||
CORE.Input.Keyboard.keyPressedQueueCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
|
||||||
// Check screen capture key (raylib key: KEY_F12)
|
|
||||||
if (CORE.Input.Keyboard.currentKeyState[301] == 1)
|
|
||||||
{
|
|
||||||
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
|
||||||
screenshotCounter++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
|
|
||||||
|
|
||||||
TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Screen confinement
|
// Screen confinement
|
||||||
|
|
|
||||||
13
src/rlgl.h
13
src/rlgl.h
|
|
@ -1100,9 +1100,12 @@ void rlFrustum(double left, double right, double bottom, double top, double znea
|
||||||
// Multiply the current matrix by an orthographic matrix generated by parameters
|
// Multiply the current matrix by an orthographic matrix generated by parameters
|
||||||
void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
|
void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
|
||||||
{
|
{
|
||||||
Matrix matOrtho = MatrixOrtho(left, right, bottom, top, znear, zfar);
|
if (((right - left) > 0) && ((bottom - top) > 0))
|
||||||
|
{
|
||||||
*RLGL.State.currentMatrix = MatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
|
Matrix matOrtho = MatrixOrtho(left, right, bottom, top, znear, zfar);
|
||||||
|
*RLGL.State.currentMatrix = MatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
|
||||||
|
}
|
||||||
|
else *RLGL.State.currentMatrix = MatrixIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -4788,8 +4791,8 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight)
|
||||||
// Count mipmap levels required
|
// Count mipmap levels required
|
||||||
while ((width != 1) && (height != 1))
|
while ((width != 1) && (height != 1))
|
||||||
{
|
{
|
||||||
if (width != 1) width /= 2;
|
width /= 2;
|
||||||
if (height != 1) height /= 2;
|
height /= 2;
|
||||||
|
|
||||||
TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height);
|
TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user