Ver código fonte

Remove unecessary spaces...

pull/223/head
Ray 8 anos atrás
pai
commit
c85dfd4bc6
7 arquivos alterados com 445 adições e 445 exclusões
  1. +49
    -49
      src/audio.c
  2. +50
    -50
      src/core.c
  3. +33
    -33
      src/models.c
  4. +13
    -13
      src/raylib.h
  5. +244
    -244
      src/rlgl.c
  6. +30
    -30
      src/text.c
  7. +26
    -26
      src/textures.c

+ 49
- 49
src/audio.c Ver arquivo

@ -231,9 +231,9 @@ Wave LoadWave(const char *fileName)
else if (strcmp(GetExtension(fileName),"rres") == 0) else if (strcmp(GetExtension(fileName),"rres") == 0)
{ {
RRESData rres = LoadResource(fileName); RRESData rres = LoadResource(fileName);
// NOTE: Parameters for RRES_WAVE type are: sampleCount, sampleRate, sampleSize, channels // NOTE: Parameters for RRES_WAVE type are: sampleCount, sampleRate, sampleSize, channels
if (rres.type == RRES_WAVE) wave = LoadWaveEx(rres.data, rres.param1, rres.param2, rres.param3, rres.param4); if (rres.type == RRES_WAVE) wave = LoadWaveEx(rres.data, rres.param1, rres.param2, rres.param3, rres.param4);
else TraceLog(WARNING, "[%s] Resource file does not contain wave data", fileName); else TraceLog(WARNING, "[%s] Resource file does not contain wave data", fileName);
@ -248,18 +248,18 @@ Wave LoadWave(const char *fileName)
Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels) Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels)
{ {
Wave wave; Wave wave;
wave.data = data; wave.data = data;
wave.sampleCount = sampleCount; wave.sampleCount = sampleCount;
wave.sampleRate = sampleRate; wave.sampleRate = sampleRate;
wave.sampleSize = sampleSize; wave.sampleSize = sampleSize;
wave.channels = channels; wave.channels = channels;
// NOTE: Copy wave data to work with, user is responsible of input data to free // NOTE: Copy wave data to work with, user is responsible of input data to free
Wave cwave = WaveCopy(wave); Wave cwave = WaveCopy(wave);
WaveFormat(&cwave, sampleRate, sampleSize, channels); WaveFormat(&cwave, sampleRate, sampleSize, channels);
return cwave; return cwave;
} }
@ -268,9 +268,9 @@ Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int
Sound LoadSound(const char *fileName) Sound LoadSound(const char *fileName)
{ {
Wave wave = LoadWave(fileName); Wave wave = LoadWave(fileName);
Sound sound = LoadSoundFromWave(wave); Sound sound = LoadSoundFromWave(wave);
UnloadWave(wave); // Sound is loaded, we can unload wave UnloadWave(wave); // Sound is loaded, we can unload wave
return sound; return sound;
@ -354,7 +354,7 @@ void UnloadWave(Wave wave)
void UnloadSound(Sound sound) void UnloadSound(Sound sound)
{ {
alSourceStop(sound.source); alSourceStop(sound.source);
alDeleteSources(1, &sound.source); alDeleteSources(1, &sound.source);
alDeleteBuffers(1, &sound.buffer); alDeleteBuffers(1, &sound.buffer);
@ -369,13 +369,13 @@ void UpdateSound(Sound sound, const void *data, int numSamples)
alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate);
alGetBufferi(sound.buffer, AL_BITS, &sampleSize); // It could also be retrieved from sound.format alGetBufferi(sound.buffer, AL_BITS, &sampleSize); // It could also be retrieved from sound.format
alGetBufferi(sound.buffer, AL_CHANNELS, &channels); // It could also be retrieved from sound.format alGetBufferi(sound.buffer, AL_CHANNELS, &channels); // It could also be retrieved from sound.format
TraceLog(DEBUG, "UpdateSound() : AL_FREQUENCY: %i", sampleRate); TraceLog(DEBUG, "UpdateSound() : AL_FREQUENCY: %i", sampleRate);
TraceLog(DEBUG, "UpdateSound() : AL_BITS: %i", sampleSize); TraceLog(DEBUG, "UpdateSound() : AL_BITS: %i", sampleSize);
TraceLog(DEBUG, "UpdateSound() : AL_CHANNELS: %i", channels); TraceLog(DEBUG, "UpdateSound() : AL_CHANNELS: %i", channels);
unsigned int dataSize = numSamples*channels*sampleSize/8; // Size of data in bytes unsigned int dataSize = numSamples*channels*sampleSize/8; // Size of data in bytes
alSourceStop(sound.source); // Stop sound alSourceStop(sound.source); // Stop sound
alSourcei(sound.source, AL_BUFFER, 0); // Unbind buffer from sound to update alSourcei(sound.source, AL_BUFFER, 0); // Unbind buffer from sound to update
//alDeleteBuffers(1, &sound.buffer); // Delete current buffer data //alDeleteBuffers(1, &sound.buffer); // Delete current buffer data
@ -463,18 +463,18 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
if (wave->sampleRate != sampleRate) if (wave->sampleRate != sampleRate)
{ {
// TODO: Resample wave data (upsampling or downsampling) // TODO: Resample wave data (upsampling or downsampling)
// NOTE 1: To downsample, you have to drop samples or average them. // NOTE 1: To downsample, you have to drop samples or average them.
// NOTE 2: To upsample, you have to interpolate new samples. // NOTE 2: To upsample, you have to interpolate new samples.
wave->sampleRate = sampleRate; wave->sampleRate = sampleRate;
} }
// Format sample size // Format sample size
// NOTE: Only supported 8 bit <--> 16 bit <--> 32 bit // NOTE: Only supported 8 bit <--> 16 bit <--> 32 bit
if (wave->sampleSize != sampleSize) if (wave->sampleSize != sampleSize)
{ {
void *data = malloc(wave->sampleCount*wave->channels*sampleSize/8); void *data = malloc(wave->sampleCount*wave->channels*sampleSize/8);
for (int i = 0; i < wave->sampleCount; i++) for (int i = 0; i < wave->sampleCount; i++)
{ {
for (int j = 0; j < wave->channels; j++) for (int j = 0; j < wave->channels; j++)
@ -484,30 +484,30 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
if (wave->sampleSize == 16) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float)(((short *)wave->data)[wave->channels*i + j])/32767.0f)*256); if (wave->sampleSize == 16) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float)(((short *)wave->data)[wave->channels*i + j])/32767.0f)*256);
else if (wave->sampleSize == 32) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float *)wave->data)[wave->channels*i + j]*127.0f + 127); else if (wave->sampleSize == 32) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float *)wave->data)[wave->channels*i + j]*127.0f + 127);
} }
else if (sampleSize == 16) else if (sampleSize == 16)
{ {
if (wave->sampleSize == 8) ((short *)data)[wave->channels*i + j] = (short)(((float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f)*32767); if (wave->sampleSize == 8) ((short *)data)[wave->channels*i + j] = (short)(((float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f)*32767);
else if (wave->sampleSize == 32) ((short *)data)[wave->channels*i + j] = (short)((((float *)wave->data)[wave->channels*i + j])*32767); else if (wave->sampleSize == 32) ((short *)data)[wave->channels*i + j] = (short)((((float *)wave->data)[wave->channels*i + j])*32767);
} }
else if (sampleSize == 32) else if (sampleSize == 32)
{ {
if (wave->sampleSize == 8) ((float *)data)[wave->channels*i + j] = (float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f; if (wave->sampleSize == 8) ((float *)data)[wave->channels*i + j] = (float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f;
else if (wave->sampleSize == 16) ((float *)data)[wave->channels*i + j] = (float)(((short *)wave->data)[wave->channels*i + j])/32767.0f; else if (wave->sampleSize == 16) ((float *)data)[wave->channels*i + j] = (float)(((short *)wave->data)[wave->channels*i + j])/32767.0f;
} }
} }
} }
wave->sampleSize = sampleSize; wave->sampleSize = sampleSize;
free(wave->data); free(wave->data);
wave->data = data; wave->data = data;
} }
// Format channels (interlaced mode) // Format channels (interlaced mode)
// NOTE: Only supported mono <--> stereo // NOTE: Only supported mono <--> stereo
if (wave->channels != channels) if (wave->channels != channels)
{ {
void *data = malloc(wave->sampleCount*channels*wave->sampleSize/8); void *data = malloc(wave->sampleCount*channels*wave->sampleSize/8);
if ((wave->channels == 1) && (channels == 2)) // mono ---> stereo (duplicate mono information) if ((wave->channels == 1) && (channels == 2)) // mono ---> stereo (duplicate mono information)
{ {
for (int i = 0; i < wave->sampleCount; i++) for (int i = 0; i < wave->sampleCount; i++)
@ -529,7 +529,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
else if (wave->sampleSize == 32) ((float *)data)[i] = (((float *)wave->data)[j] + ((float *)wave->data)[j + 1])/2.0f; else if (wave->sampleSize == 32) ((float *)data)[i] = (((float *)wave->data)[j] + ((float *)wave->data)[j + 1])/2.0f;
} }
} }
// TODO: Add/remove additional interlaced channels // TODO: Add/remove additional interlaced channels
wave->channels = channels; wave->channels = channels;
@ -563,15 +563,15 @@ Wave WaveCopy(Wave wave)
// NOTE: Security check in case of out-of-range // NOTE: Security check in case of out-of-range
void WaveCrop(Wave *wave, int initSample, int finalSample) void WaveCrop(Wave *wave, int initSample, int finalSample)
{ {
if ((initSample >= 0) && (initSample < finalSample) && if ((initSample >= 0) && (initSample < finalSample) &&
(finalSample > 0) && (finalSample < wave->sampleCount)) (finalSample > 0) && (finalSample < wave->sampleCount))
{ {
int sampleCount = finalSample - initSample; int sampleCount = finalSample - initSample;
void *data = malloc(sampleCount*wave->channels*wave->sampleSize/8); void *data = malloc(sampleCount*wave->channels*wave->sampleSize/8);
memcpy(data, wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8); memcpy(data, wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8);
free(wave->data); free(wave->data);
wave->data = data; wave->data = data;
} }
@ -583,7 +583,7 @@ void WaveCrop(Wave *wave, int initSample, int finalSample)
float *GetWaveData(Wave wave) float *GetWaveData(Wave wave)
{ {
float *samples = (float *)malloc(wave.sampleCount*wave.channels*sizeof(float)); float *samples = (float *)malloc(wave.sampleCount*wave.channels*sizeof(float));
for (int i = 0; i < wave.sampleCount; i++) for (int i = 0; i < wave.sampleCount; i++)
{ {
for (int j = 0; j < wave.channels; j++) for (int j = 0; j < wave.channels; j++)
@ -593,7 +593,7 @@ float *GetWaveData(Wave wave)
else if (wave.sampleSize == 32) samples[wave.channels*i + j] = ((float *)wave.data)[wave.channels*i + j]; else if (wave.sampleSize == 32) samples[wave.channels*i + j] = ((float *)wave.data)[wave.channels*i + j];
} }
} }
return samples; return samples;
} }
@ -632,7 +632,7 @@ Music LoadMusicStream(const char *fileName)
else if (strcmp(GetExtension(fileName), "flac") == 0) else if (strcmp(GetExtension(fileName), "flac") == 0)
{ {
music->ctxFlac = drflac_open_file(fileName); music->ctxFlac = drflac_open_file(fileName);
if (music->ctxFlac == NULL) TraceLog(WARNING, "[%s] FLAC audio file could not be opened", fileName); if (music->ctxFlac == NULL) TraceLog(WARNING, "[%s] FLAC audio file could not be opened", fileName);
else else
{ {
@ -641,7 +641,7 @@ Music LoadMusicStream(const char *fileName)
music->samplesLeft = music->totalSamples; music->samplesLeft = music->totalSamples;
music->ctxType = MUSIC_AUDIO_FLAC; music->ctxType = MUSIC_AUDIO_FLAC;
music->loop = true; // We loop by default music->loop = true; // We loop by default
TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples);
TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate); TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate);
TraceLog(DEBUG, "[%s] FLAC bits per sample: %i", fileName, music->ctxFlac->bitsPerSample); TraceLog(DEBUG, "[%s] FLAC bits per sample: %i", fileName, music->ctxFlac->bitsPerSample);
@ -728,7 +728,7 @@ void ResumeMusicStream(Music music)
void StopMusicStream(Music music) void StopMusicStream(Music music)
{ {
alSourceStop(music->stream.source); alSourceStop(music->stream.source);
switch (music->ctxType) switch (music->ctxType)
{ {
case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break; case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break;
@ -736,7 +736,7 @@ void StopMusicStream(Music music)
case MUSIC_MODULE_MOD: jar_mod_seek_start(&music->ctxMod); break; case MUSIC_MODULE_MOD: jar_mod_seek_start(&music->ctxMod); break;
default: break; default: break;
} }
music->samplesLeft = music->totalSamples; music->samplesLeft = music->totalSamples;
} }
@ -745,14 +745,14 @@ void UpdateMusicStream(Music music)
{ {
ALenum state; ALenum state;
ALint processed = 0; ALint processed = 0;
alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state); // Get music stream state alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state); // Get music stream state
alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); // Get processed buffers alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); // Get processed buffers
if (processed > 0) if (processed > 0)
{ {
bool active = true; bool active = true;
// NOTE: Using dynamic allocation because it could require more than 16KB // NOTE: Using dynamic allocation because it could require more than 16KB
void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.channels*music->stream.sampleSize/8, 1); void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.channels*music->stream.sampleSize/8, 1);
@ -764,7 +764,7 @@ void UpdateMusicStream(Music music)
{ {
if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE; if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE;
else numSamples = music->samplesLeft; else numSamples = music->samplesLeft;
// TODO: Really don't like ctxType thingy... // TODO: Really don't like ctxType thingy...
switch (music->ctxType) switch (music->ctxType)
{ {
@ -784,7 +784,7 @@ void UpdateMusicStream(Music music)
case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); break; case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); break;
default: break; default: break;
} }
UpdateAudioStream(music->stream, pcm, numSamples); UpdateAudioStream(music->stream, pcm, numSamples);
music->samplesLeft -= numSamples; music->samplesLeft -= numSamples;
@ -794,12 +794,12 @@ void UpdateMusicStream(Music music)
break; break;
} }
} }
// This error is registered when UpdateAudioStream() fails // This error is registered when UpdateAudioStream() fails
if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data..."); if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data...");
// Reset audio stream for looping // Reset audio stream for looping
if (!active) if (!active)
{ {
StopMusicStream(music); // Stop music (and reset) StopMusicStream(music); // Stop music (and reset)
if (music->loop) PlayMusicStream(music); // Play again if (music->loop) PlayMusicStream(music); // Play again
@ -810,7 +810,7 @@ void UpdateMusicStream(Music music)
// just make sure to play again on window restore // just make sure to play again on window restore
if (state != AL_PLAYING) PlayMusicStream(music); if (state != AL_PLAYING) PlayMusicStream(music);
} }
free(pcm); free(pcm);
} }
} }
@ -866,7 +866,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
stream.sampleRate = sampleRate; stream.sampleRate = sampleRate;
stream.sampleSize = sampleSize; stream.sampleSize = sampleSize;
// Only mono and stereo channels are supported, more channels require AL_EXT_MCFORMATS extension // Only mono and stereo channels are supported, more channels require AL_EXT_MCFORMATS extension
if ((channels > 0) && (channels < 3)) stream.channels = channels; if ((channels > 0) && (channels < 3)) stream.channels = channels;
else else
@ -910,12 +910,12 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
// Initialize buffer with zeros by default // Initialize buffer with zeros by default
// NOTE: Using dynamic allocation because it requires more than 16KB // NOTE: Using dynamic allocation because it requires more than 16KB
void *pcm = calloc(AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, 1); void *pcm = calloc(AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, 1);
for (int i = 0; i < MAX_STREAM_BUFFERS; i++) for (int i = 0; i < MAX_STREAM_BUFFERS; i++)
{ {
alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, stream.sampleRate); alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, stream.sampleRate);
} }
free(pcm); free(pcm);
alSourceQueueBuffers(stream.source, MAX_STREAM_BUFFERS, stream.buffers); alSourceQueueBuffers(stream.source, MAX_STREAM_BUFFERS, stream.buffers);
@ -1095,7 +1095,7 @@ static Wave LoadWAV(const char *fileName)
wave.sampleRate = wavFormat.sampleRate; wave.sampleRate = wavFormat.sampleRate;
wave.sampleSize = wavFormat.bitsPerSample; wave.sampleSize = wavFormat.bitsPerSample;
wave.channels = wavFormat.numChannels; wave.channels = wavFormat.numChannels;
// NOTE: Only support 8 bit, 16 bit and 32 bit sample sizes // NOTE: Only support 8 bit, 16 bit and 32 bit sample sizes
if ((wave.sampleSize != 8) && (wave.sampleSize != 16) && (wave.sampleSize != 32)) if ((wave.sampleSize != 8) && (wave.sampleSize != 16) && (wave.sampleSize != 32))
{ {
@ -1104,16 +1104,16 @@ static Wave LoadWAV(const char *fileName)
} }
// NOTE: Only support up to 2 channels (mono, stereo) // NOTE: Only support up to 2 channels (mono, stereo)
if (wave.channels > 2) if (wave.channels > 2)
{ {
WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2); WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2);
TraceLog(WARNING, "[%s] WAV channels number (%i) not supported, converted to 2 channels", fileName, wave.channels); TraceLog(WARNING, "[%s] WAV channels number (%i) not supported, converted to 2 channels", fileName, wave.channels);
} }
// NOTE: subChunkSize comes in bytes, we need to translate it to number of samples // NOTE: subChunkSize comes in bytes, we need to translate it to number of samples
wave.sampleCount = (wavData.subChunkSize/(wave.sampleSize/8))/wave.channels; wave.sampleCount = (wavData.subChunkSize/(wave.sampleSize/8))/wave.channels;
TraceLog(INFO, "[%s] WAV file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); TraceLog(INFO, "[%s] WAV file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo");
} }
} }
} }
@ -1145,7 +1145,7 @@ static Wave LoadOGG(const char *fileName)
wave.sampleSize = 16; // 16 bit per sample (short) wave.sampleSize = 16; // 16 bit per sample (short)
wave.channels = info.channels; wave.channels = info.channels;
wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile); wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile);
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile); float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds); if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
@ -1173,16 +1173,16 @@ static Wave LoadFLAC(const char *fileName)
// Decode an entire FLAC file in one go // Decode an entire FLAC file in one go
uint64_t totalSampleCount; uint64_t totalSampleCount;
wave.data = drflac_open_and_decode_file_s16(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount); wave.data = drflac_open_and_decode_file_s16(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount);
wave.sampleCount = (int)totalSampleCount/wave.channels; wave.sampleCount = (int)totalSampleCount/wave.channels;
wave.sampleSize = 16; wave.sampleSize = 16;
// NOTE: Only support up to 2 channels (mono, stereo) // NOTE: Only support up to 2 channels (mono, stereo)
if (wave.channels > 2) TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported", fileName, wave.channels); if (wave.channels > 2) TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported", fileName, wave.channels);
if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName); if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName);
else TraceLog(INFO, "[%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); else TraceLog(INFO, "[%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo");
return wave; return wave;
} }

+ 50
- 50
src/core.c Ver arquivo

@ -9,7 +9,7 @@
* External libs: * External libs:
* GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX) * GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX)
* raymath - 3D math functionality (Vector3, Matrix, Quaternion) * raymath - 3D math functionality (Vector3, Matrix, Quaternion)
* camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person) * camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person)
* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs) * gestures - Gestures system for touch-ready devices (or simulated from mouse inputs)
* *
* Module Configuration Flags: * Module Configuration Flags:
@ -103,7 +103,7 @@
#include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition #include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
#include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...) #include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...)
#include <linux/joystick.h> // Linux: Joystick support library #include <linux/joystick.h> // Linux: Joystick support library
#include "bcm_host.h" // Raspberry Pi VideoCore IV access functions #include "bcm_host.h" // Raspberry Pi VideoCore IV access functions
#include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions
@ -488,9 +488,9 @@ void CloseWindow(void)
// Wait for mouse and gamepad threads to finish before closing // Wait for mouse and gamepad threads to finish before closing
// NOTE: Those threads should already have finished at this point // NOTE: Those threads should already have finished at this point
// because they are controlled by windowShouldClose variable // because they are controlled by windowShouldClose variable
windowShouldClose = true; // Added to force threads to exit when the close window is called windowShouldClose = true; // Added to force threads to exit when the close window is called
pthread_join(mouseThreadId, NULL); pthread_join(mouseThreadId, NULL);
pthread_join(touchThreadId, NULL); pthread_join(touchThreadId, NULL);
pthread_join(gamepadThreadId, NULL); pthread_join(gamepadThreadId, NULL);
@ -649,14 +649,14 @@ void EndDrawing(void)
frameTime = updateTime + drawTime; frameTime = updateTime + drawTime;
// Wait for some milliseconds... // Wait for some milliseconds...
if (frameTime < targetTime) if (frameTime < targetTime)
{ {
Wait((int)((targetTime - frameTime)*1000)); Wait((int)((targetTime - frameTime)*1000));
currentTime = GetTime(); currentTime = GetTime();
double extraTime = currentTime - previousTime; double extraTime = currentTime - previousTime;
previousTime = currentTime; previousTime = currentTime;
frameTime = updateTime + drawTime + extraTime; frameTime = updateTime + drawTime + extraTime;
} }
} }
@ -1147,7 +1147,7 @@ bool IsKeyDown(int key)
bool IsKeyReleased(int key) bool IsKeyReleased(int key)
{ {
bool released = false; bool released = false;
if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true; if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true;
else released = false; else released = false;
@ -1182,7 +1182,7 @@ void SetExitKey(int key)
bool IsGamepadAvailable(int gamepad) bool IsGamepadAvailable(int gamepad)
{ {
bool result = false; bool result = false;
#if !defined(PLATFORM_ANDROID) #if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true; if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true;
#endif #endif
@ -1196,7 +1196,7 @@ bool IsGamepadName(int gamepad, const char *name)
bool result = false; bool result = false;
#if !defined(PLATFORM_ANDROID) #if !defined(PLATFORM_ANDROID)
const char *gamepadName = NULL; const char *gamepadName = NULL;
if (gamepadReady[gamepad]) gamepadName = GetGamepadName(gamepad); if (gamepadReady[gamepad]) gamepadName = GetGamepadName(gamepad);
if ((name != NULL) && (gamepadName != NULL)) result = (strcmp(name, gamepadName) == 0); if ((name != NULL) && (gamepadName != NULL)) result = (strcmp(name, gamepadName) == 0);
@ -1235,7 +1235,7 @@ int GetGamepadAxisCount(int gamepad)
float GetGamepadAxisMovement(int gamepad, int axis) float GetGamepadAxisMovement(int gamepad, int axis)
{ {
float value = 0; float value = 0;
#if !defined(PLATFORM_ANDROID) #if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (axis < MAX_GAMEPAD_AXIS)) value = gamepadAxisState[gamepad][axis]; if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (axis < MAX_GAMEPAD_AXIS)) value = gamepadAxisState[gamepad][axis];
#endif #endif
@ -1249,8 +1249,8 @@ bool IsGamepadButtonPressed(int gamepad, int button)
bool pressed = false; bool pressed = false;
#if !defined(PLATFORM_ANDROID) #if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
(currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) && (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
(currentGamepadState[gamepad][button] == 1)) pressed = true; (currentGamepadState[gamepad][button] == 1)) pressed = true;
#endif #endif
@ -1274,10 +1274,10 @@ bool IsGamepadButtonDown(int gamepad, int button)
bool IsGamepadButtonReleased(int gamepad, int button) bool IsGamepadButtonReleased(int gamepad, int button)
{ {
bool released = false; bool released = false;
#if !defined(PLATFORM_ANDROID) #if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
(currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) && (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
(currentGamepadState[gamepad][button] == 0)) released = true; (currentGamepadState[gamepad][button] == 0)) released = true;
#endif #endif
@ -1290,7 +1290,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
bool result = false; bool result = false;
#if !defined(PLATFORM_ANDROID) #if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
(currentGamepadState[gamepad][button] == 0)) result = true; (currentGamepadState[gamepad][button] == 0)) result = true;
#endif #endif
@ -1503,7 +1503,7 @@ static void InitGraphicsDevice(int width, int height)
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window
} }
else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
//glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window //glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window
//glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
//glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default) //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default)
@ -1941,7 +1941,7 @@ static double GetTime(void)
// Wait for some milliseconds (stop program execution) // Wait for some milliseconds (stop program execution)
static void Wait(int ms) static void Wait(int ms)
{ {
#if defined _WIN32 #if defined _WIN32
Sleep(ms); Sleep(ms);
#elif defined __linux || defined(PLATFORM_WEB) #elif defined __linux || defined(PLATFORM_WEB)
struct timespec req = { 0 }; struct timespec req = { 0 };
@ -1949,7 +1949,7 @@ static void Wait(int ms)
ms -= (sec*1000); ms -= (sec*1000);
req.tv_sec=sec; req.tv_sec=sec;
req.tv_nsec=ms*1000000L; req.tv_nsec=ms*1000000L;
// NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated. // NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated.
while (nanosleep(&req,&req) == -1) continue; while (nanosleep(&req,&req) == -1) continue;
//#elif defined __APPLE__ //#elif defined __APPLE__
@ -1999,10 +1999,10 @@ static void PollInputEvents(void)
// NOTE: Gestures update must be called every frame to reset gestures correctly // NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame // because ProcessGestureEvent() is just called on an event, not every frame
UpdateGestures(); UpdateGestures();
// Reset last key pressed registered // Reset last key pressed registered
lastKeyPressed = -1; lastKeyPressed = -1;
#if !defined(PLATFORM_RPI) #if !defined(PLATFORM_RPI)
// Reset last gamepad button/axis registered state // Reset last gamepad button/axis registered state
lastGamepadButtonPressed = -1; lastGamepadButtonPressed = -1;
@ -2018,7 +2018,7 @@ static void PollInputEvents(void)
mousePosition.x = (float)mouseX; mousePosition.x = (float)mouseX;
mousePosition.y = (float)mouseY; mousePosition.y = (float)mouseY;
// Keyboard input polling (automatically managed by GLFW3 through callback) // Keyboard input polling (automatically managed by GLFW3 through callback)
// Register previous keys states // Register previous keys states
@ -2039,7 +2039,7 @@ static void PollInputEvents(void)
if (glfwJoystickPresent(i)) gamepadReady[i] = true; if (glfwJoystickPresent(i)) gamepadReady[i] = true;
else gamepadReady[i] = false; else gamepadReady[i] = false;
} }
// Register gamepads buttons events // Register gamepads buttons events
for (int i = 0; i < MAX_GAMEPADS; i++) for (int i = 0; i < MAX_GAMEPADS; i++)
{ {
@ -2047,14 +2047,14 @@ static void PollInputEvents(void)
{ {
// Register previous gamepad states // Register previous gamepad states
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k]; for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
// Get current gamepad state // Get current gamepad state
// NOTE: There is no callback available, so we get it manually // NOTE: There is no callback available, so we get it manually
const unsigned char *buttons; const unsigned char *buttons;
int buttonsCount; int buttonsCount;
buttons = glfwGetJoystickButtons(i, &buttonsCount); buttons = glfwGetJoystickButtons(i, &buttonsCount);
for (int k = 0; (buttons != NULL) && (k < buttonsCount) && (buttonsCount < MAX_GAMEPAD_BUTTONS); k++) for (int k = 0; (buttons != NULL) && (k < buttonsCount) && (buttonsCount < MAX_GAMEPAD_BUTTONS); k++)
{ {
if (buttons[k] == GLFW_PRESS) if (buttons[k] == GLFW_PRESS)
@ -2064,18 +2064,18 @@ static void PollInputEvents(void)
} }
else currentGamepadState[i][k] = 0; else currentGamepadState[i][k] = 0;
} }
// Get current axis state // Get current axis state
const float *axes; const float *axes;
int axisCount = 0; int axisCount = 0;
axes = glfwGetJoystickAxes(i, &axisCount); axes = glfwGetJoystickAxes(i, &axisCount);
for (int k = 0; (axes != NULL) && (k < axisCount) && (k < MAX_GAMEPAD_AXIS); k++) for (int k = 0; (axes != NULL) && (k < axisCount) && (k < MAX_GAMEPAD_AXIS); k++)
{ {
gamepadAxisState[i][k] = axes[k]; gamepadAxisState[i][k] = axes[k];
} }
gamepadAxisCount = axisCount; gamepadAxisCount = axisCount;
} }
} }
@ -2088,16 +2088,16 @@ static void PollInputEvents(void)
#if defined(PLATFORM_WEB) #if defined(PLATFORM_WEB)
// Get number of gamepads connected // Get number of gamepads connected
int numGamepads = emscripten_get_num_gamepads(); int numGamepads = emscripten_get_num_gamepads();
for (int i = 0; (i < numGamepads) && (i < MAX_GAMEPADS); i++) for (int i = 0; (i < numGamepads) && (i < MAX_GAMEPADS); i++)
{ {
// Register previous gamepad button states // Register previous gamepad button states
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k]; for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
EmscriptenGamepadEvent gamepadState; EmscriptenGamepadEvent gamepadState;
int result = emscripten_get_gamepad_status(i, &gamepadState); int result = emscripten_get_gamepad_status(i, &gamepadState);
if (result == EMSCRIPTEN_RESULT_SUCCESS) if (result == EMSCRIPTEN_RESULT_SUCCESS)
{ {
// Register buttons data for every connected gamepad // Register buttons data for every connected gamepad
@ -2109,16 +2109,16 @@ static void PollInputEvents(void)
lastGamepadButtonPressed = j; lastGamepadButtonPressed = j;
} }
else currentGamepadState[i][j] = 0; else currentGamepadState[i][j] = 0;
//printf("Gamepad %d, button %d: Digital: %d, Analog: %g\n", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); //printf("Gamepad %d, button %d: Digital: %d, Analog: %g\n", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]);
} }
// Register axis data for every connected gamepad // Register axis data for every connected gamepad
for (int j = 0; (j < gamepadState.numAxes) && (j < MAX_GAMEPAD_AXIS); j++) for (int j = 0; (j < gamepadState.numAxes) && (j < MAX_GAMEPAD_AXIS); j++)
{ {
gamepadAxisState[i][j] = gamepadState.axis[j]; gamepadAxisState[i][j] = gamepadState.axis[j];
} }
gamepadAxisCount = gamepadState.numAxes; gamepadAxisCount = gamepadState.numAxes;
} }
} }
@ -2665,16 +2665,16 @@ static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadE
{ {
/* /*
printf("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"\n", printf("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"\n",
eventType != 0 ? emscripten_event_type_to_string(eventType) : "Gamepad state", eventType != 0 ? emscripten_event_type_to_string(eventType) : "Gamepad state",
gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping);
for(int i = 0; i < gamepadEvent->numAxes; ++i) printf("Axis %d: %g\n", i, gamepadEvent->axis[i]); for(int i = 0; i < gamepadEvent->numAxes; ++i) printf("Axis %d: %g\n", i, gamepadEvent->axis[i]);
for(int i = 0; i < gamepadEvent->numButtons; ++i) printf("Button %d: Digital: %d, Analog: %g\n", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); for(int i = 0; i < gamepadEvent->numButtons; ++i) printf("Button %d: Digital: %d, Analog: %g\n", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
*/ */
if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) gamepadReady[gamepadEvent->index] = true; if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) gamepadReady[gamepadEvent->index] = true;
else gamepadReady[gamepadEvent->index] = false; else gamepadReady[gamepadEvent->index] = false;
// TODO: Test gamepadEvent->index // TODO: Test gamepadEvent->index
return 0; return 0;
@ -2935,7 +2935,7 @@ static void InitTouch(void)
} }
// Touch reading thread. // Touch reading thread.
// This reads from a Virtual Input Event /dev/input/event4 which is // This reads from a Virtual Input Event /dev/input/event4 which is
// created by the ts_uinput daemon. This takes, filters and scales // created by the ts_uinput daemon. This takes, filters and scales
// raw input from the Touchscreen (which appears in /dev/input/event3) // raw input from the Touchscreen (which appears in /dev/input/event3)
// based on the Calibration data referenced by tslib. // based on the Calibration data referenced by tslib.
@ -2949,7 +2949,7 @@ static void *TouchThread(void *arg)
if (read(touchStream, &ev, sizeof(ev)) == (int)sizeof(ev)) if (read(touchStream, &ev, sizeof(ev)) == (int)sizeof(ev))
{ {
// if pressure > 0 then simulate left mouse button click // if pressure > 0 then simulate left mouse button click
if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0 && currentMouseState[0] == 1) if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0 && currentMouseState[0] == 1)
{ {
currentMouseState[0] = 0; currentMouseState[0] = 0;
gestureEvent.touchAction = TOUCH_UP; gestureEvent.touchAction = TOUCH_UP;
@ -2963,10 +2963,10 @@ static void *TouchThread(void *arg)
gestureEvent.position[1].x /= (float)GetScreenWidth(); gestureEvent.position[1].x /= (float)GetScreenWidth();
gestureEvent.position[1].y /= (float)GetScreenHeight(); gestureEvent.position[1].y /= (float)GetScreenHeight();
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
} }
if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0 && currentMouseState[0] == 0) if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0 && currentMouseState[0] == 0)
{ {
currentMouseState[0] = 1; currentMouseState[0] = 1;
gestureEvent.touchAction = TOUCH_DOWN; gestureEvent.touchAction = TOUCH_DOWN;
gestureEvent.pointCount = 1; gestureEvent.pointCount = 1;
gestureEvent.pointerId[0] = 0; gestureEvent.pointerId[0] = 0;
@ -2978,9 +2978,9 @@ static void *TouchThread(void *arg)
gestureEvent.position[1].x /= (float)GetScreenWidth(); gestureEvent.position[1].x /= (float)GetScreenWidth();
gestureEvent.position[1].y /= (float)GetScreenHeight(); gestureEvent.position[1].y /= (float)GetScreenHeight();
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
} }
// x & y values supplied by event4 have been scaled & de-jittered using tslib calibration data // x & y values supplied by event4 have been scaled & de-jittered using tslib calibration data
if (ev.type == EV_ABS && ev.code == 0) if (ev.type == EV_ABS && ev.code == 0)
{ {
mousePosition.x = ev.value; mousePosition.x = ev.value;
if (mousePosition.x < 0) mousePosition.x = 0; if (mousePosition.x < 0) mousePosition.x = 0;
@ -2997,7 +2997,7 @@ static void *TouchThread(void *arg)
gestureEvent.position[1].y /= (float)GetScreenHeight(); gestureEvent.position[1].y /= (float)GetScreenHeight();
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
} }
if (ev.type == EV_ABS && ev.code == 1) if (ev.type == EV_ABS && ev.code == 1)
{ {
mousePosition.y = ev.value; mousePosition.y = ev.value;
if (mousePosition.y < 0) mousePosition.y = 0; if (mousePosition.y < 0) mousePosition.y = 0;
@ -3014,7 +3014,7 @@ static void *TouchThread(void *arg)
gestureEvent.position[1].y /= (float)GetScreenHeight(); gestureEvent.position[1].y /= (float)GetScreenHeight();
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
} }
} }
} }
return NULL; return NULL;
@ -3084,7 +3084,7 @@ static void *GamepadThread(void *arg)
{ {
// 1 - button pressed, 0 - button released // 1 - button pressed, 0 - button released
currentGamepadState[i][gamepadEvent.number] = (int)gamepadEvent.value; currentGamepadState[i][gamepadEvent.number] = (int)gamepadEvent.value;
if ((int)gamepadEvent.value == 1) lastGamepadButtonPressed = gamepadEvent.number; if ((int)gamepadEvent.value == 1) lastGamepadButtonPressed = gamepadEvent.number;
else lastGamepadButtonPressed = -1; else lastGamepadButtonPressed = -1;
} }

+ 33
- 33
src/models.c Ver arquivo

@ -584,7 +584,7 @@ Mesh LoadMesh(const char *fileName)
if (mesh.vertexCount == 0) TraceLog(WARNING, "Mesh could not be loaded"); if (mesh.vertexCount == 0) TraceLog(WARNING, "Mesh could not be loaded");
else rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh) else rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh)
// TODO: Initialize default mesh data in case loading fails, maybe a cube? // TODO: Initialize default mesh data in case loading fails, maybe a cube?
return mesh; return mesh;
@ -607,7 +607,7 @@ Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color
mesh.indices = NULL; mesh.indices = NULL;
rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh) rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh)
return mesh; return mesh;
} }
@ -668,7 +668,7 @@ Model LoadCubicmap(Image cubicmap)
return model; return model;
} }
// Unload mesh from memory (RAM and/or VRAM) // Unload mesh from memory (RAM and/or VRAM)
void UnloadMesh(Mesh *mesh) void UnloadMesh(Mesh *mesh)
{ {
@ -1438,34 +1438,34 @@ RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh)
int triangleCount = mesh->vertexCount/3; int triangleCount = mesh->vertexCount/3;
// Test against all triangles in mesh // Test against all triangles in mesh
for (int i = 0; i < triangleCount; i++) for (int i = 0; i < triangleCount; i++)
{ {
Vector3 a, b, c; Vector3 a, b, c;
Vector3 *vertdata = (Vector3 *)mesh->vertices; Vector3 *vertdata = (Vector3 *)mesh->vertices;
if (mesh->indices)
if (mesh->indices)
{ {
a = vertdata[mesh->indices[i*3 + 0]]; a = vertdata[mesh->indices[i*3 + 0]];
b = vertdata[mesh->indices[i*3 + 1]]; b = vertdata[mesh->indices[i*3 + 1]];
c = vertdata[mesh->indices[i*3 + 2]]; c = vertdata[mesh->indices[i*3 + 2]];
} }
else else
{ {
a = vertdata[i*3 + 0]; a = vertdata[i*3 + 0];
b = vertdata[i*3 + 1]; b = vertdata[i*3 + 1];
c = vertdata[i*3 + 2]; c = vertdata[i*3 + 2];
} }
RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, a, b, c); RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, a, b, c);
if (triHitInfo.hit)
if (triHitInfo.hit)
{ {
// Save the closest hit triangle // Save the closest hit triangle
if ((!result.hit) || (result.distance > triHitInfo.distance)) result = triHitInfo; if ((!result.hit) || (result.distance > triHitInfo.distance)) result = triHitInfo;
} }
} }
return result; return result;
} }
// Get collision info between ray and triangle // Get collision info between ray and triangle
@ -1478,44 +1478,44 @@ RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3)
Vector3 p, q, tv; Vector3 p, q, tv;
float det, invDet, u, v, t; float det, invDet, u, v, t;
RayHitInfo result = {0}; RayHitInfo result = {0};
// Find vectors for two edges sharing V1 // Find vectors for two edges sharing V1
edge1 = VectorSubtract(p2, p1); edge1 = VectorSubtract(p2, p1);
edge2 = VectorSubtract(p3, p1); edge2 = VectorSubtract(p3, p1);
// Begin calculating determinant - also used to calculate u parameter // Begin calculating determinant - also used to calculate u parameter
p = VectorCrossProduct(ray.direction, edge2); p = VectorCrossProduct(ray.direction, edge2);
// If determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle // If determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle
det = VectorDotProduct(edge1, p); det = VectorDotProduct(edge1, p);
// Avoid culling! // Avoid culling!
if ((det > -EPSILON) && (det < EPSILON)) return result; if ((det > -EPSILON) && (det < EPSILON)) return result;
invDet = 1.0f/det; invDet = 1.0f/det;
// Calculate distance from V1 to ray origin // Calculate distance from V1 to ray origin
tv = VectorSubtract(ray.position, p1); tv = VectorSubtract(ray.position, p1);
// Calculate u parameter and test bound // Calculate u parameter and test bound
u = VectorDotProduct(tv, p)*invDet; u = VectorDotProduct(tv, p)*invDet;
// The intersection lies outside of the triangle // The intersection lies outside of the triangle
if ((u < 0.0f) || (u > 1.0f)) return result; if ((u < 0.0f) || (u > 1.0f)) return result;
// Prepare to test v parameter // Prepare to test v parameter
q = VectorCrossProduct(tv, edge1); q = VectorCrossProduct(tv, edge1);
// Calculate V parameter and test bound // Calculate V parameter and test bound
v = VectorDotProduct(ray.direction, q)*invDet; v = VectorDotProduct(ray.direction, q)*invDet;
// The intersection lies outside of the triangle // The intersection lies outside of the triangle
if ((v < 0.0f) || ((u + v) > 1.0f)) return result; if ((v < 0.0f) || ((u + v) > 1.0f)) return result;
t = VectorDotProduct(edge2, q)*invDet; t = VectorDotProduct(edge2, q)*invDet;
if (t > EPSILON)
if (t > EPSILON) {
{
// Ray hit, get hit point and normal // Ray hit, get hit point and normal
result.hit = true; result.hit = true;
result.distance = t; result.distance = t;
@ -1523,10 +1523,10 @@ RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3)
result.hitNormal = VectorCrossProduct(edge1, edge2); result.hitNormal = VectorCrossProduct(edge1, edge2);
VectorNormalize(&result.hitNormal); VectorNormalize(&result.hitNormal);
Vector3 rayDir = ray.direction; Vector3 rayDir = ray.direction;
VectorScale(&rayDir, t); VectorScale(&rayDir, t);
result.hitPosition = VectorAdd(ray.position, rayDir); result.hitPosition = VectorAdd(ray.position, rayDir);
} }
return result; return result;
} }
@ -1540,8 +1540,8 @@ RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight)
if (fabsf(ray.direction.y) > EPSILON) if (fabsf(ray.direction.y) > EPSILON)
{ {
float t = (ray.position.y - groundHeight)/-ray.direction.y; float t = (ray.position.y - groundHeight)/-ray.direction.y;
if (t >= 0.0)
if (t >= 0.0)
{ {
Vector3 rayDir = ray.direction; Vector3 rayDir = ray.direction;
VectorScale(&rayDir, t); VectorScale(&rayDir, t);
@ -1551,7 +1551,7 @@ RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight)
result.hitPosition = VectorAdd(ray.position, rayDir); result.hitPosition = VectorAdd(ray.position, rayDir);
} }
} }
return result; return result;
} }

+ 13
- 13
src/raylib.h Ver arquivo

@ -593,21 +593,21 @@ typedef enum {
// rRES data returned when reading a resource, it contains all required data for user (24 byte) // rRES data returned when reading a resource, it contains all required data for user (24 byte)
typedef struct { typedef struct {
unsigned int type; // Resource type (4 byte) unsigned int type; // Resource type (4 byte)
unsigned int param1; // Resouce parameter 1 (4 byte) unsigned int param1; // Resouce parameter 1 (4 byte)
unsigned int param2; // Resouce parameter 2 (4 byte) unsigned int param2; // Resouce parameter 2 (4 byte)
unsigned int param3; // Resouce parameter 3 (4 byte) unsigned int param3; // Resouce parameter 3 (4 byte)
unsigned int param4; // Resouce parameter 4 (4 byte) unsigned int param4; // Resouce parameter 4 (4 byte)
void *data; // Resource data pointer (4 byte) void *data; // Resource data pointer (4 byte)
} RRESData; } RRESData;
typedef enum { typedef enum {
RRES_RAW = 0, RRES_RAW = 0,
RRES_IMAGE, RRES_IMAGE,
RRES_WAVE, RRES_WAVE,
RRES_VERTEX, RRES_VERTEX,
RRES_TEXT RRES_TEXT
} RRESDataType; } RRESDataType;
#ifdef __cplusplus #ifdef __cplusplus
@ -800,7 +800,7 @@ RLAPI Image ImageText(const char *text, int fontSize, Color color);
RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination)
RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text,
float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally
@ -876,15 +876,15 @@ RLAPI Material LoadDefaultMaterial(void);
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis,
float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis,
float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec,
Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
@ -892,7 +892,7 @@ RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere
RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius,
Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point
RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh

+ 244
- 244
src/rlgl.c
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 30
- 30
src/text.c Ver arquivo

@ -286,17 +286,17 @@ SpriteFont LoadSpriteFont(const char *fileName)
SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars) SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars)
{ {
SpriteFont spriteFont = { 0 }; SpriteFont spriteFont = { 0 };
if (strcmp(GetExtension(fileName),"ttf") == 0)
if (strcmp(GetExtension(fileName),"ttf") == 0)
{ {
if ((fontChars == NULL) || (numChars == 0)) if ((fontChars == NULL) || (numChars == 0))
{ {
int totalChars = 95; // Default charset [32..126] int totalChars = 95; // Default charset [32..126]
int *defaultFontChars = (int *)malloc(totalChars*sizeof(int)); int *defaultFontChars = (int *)malloc(totalChars*sizeof(int));
for (int i = 0; i < totalChars; i++) defaultFontChars[i] = i + 32; // Default first character: SPACE[32] for (int i = 0; i < totalChars; i++) defaultFontChars[i] = i + 32; // Default first character: SPACE[32]
spriteFont = LoadTTF(fileName, fontSize, totalChars, defaultFontChars); spriteFont = LoadTTF(fileName, fontSize, totalChars, defaultFontChars);
} }
else spriteFont = LoadTTF(fileName, fontSize, numChars, fontChars); else spriteFont = LoadTTF(fileName, fontSize, numChars, fontChars);
@ -353,10 +353,10 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
int textOffsetX = 0; // Offset between characters int textOffsetX = 0; // Offset between characters
int textOffsetY = 0; // Required for line break! int textOffsetY = 0; // Required for line break!
float scaleFactor; float scaleFactor;
unsigned char letter; // Current character unsigned char letter; // Current character
int index; // Index position in sprite font int index; // Index position in sprite font
scaleFactor = fontSize/spriteFont.size; scaleFactor = fontSize/spriteFont.size;
// NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly
@ -388,10 +388,10 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
} }
else index = GetCharIndex(spriteFont, (int)text[i]); else index = GetCharIndex(spriteFont, (int)text[i]);
DrawTexturePro(spriteFont.texture, spriteFont.charRecs[index], DrawTexturePro(spriteFont.texture, spriteFont.charRecs[index],
(Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[index].x*scaleFactor, (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[index].x*scaleFactor,
position.y + textOffsetY + spriteFont.charOffsets[index].y*scaleFactor, position.y + textOffsetY + spriteFont.charOffsets[index].y*scaleFactor,
spriteFont.charRecs[index].width*scaleFactor, spriteFont.charRecs[index].width*scaleFactor,
spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint);
if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing); if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing);
@ -476,7 +476,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i
if (text[i] != '\n') if (text[i] != '\n')
{ {
int index = GetCharIndex(spriteFont, (int)text[i]); int index = GetCharIndex(spriteFont, (int)text[i]);
if (spriteFont.charAdvanceX[index] != 0) textWidth += spriteFont.charAdvanceX[index]; if (spriteFont.charAdvanceX[index] != 0) textWidth += spriteFont.charAdvanceX[index];
else textWidth += (spriteFont.charRecs[index].width + spriteFont.charOffsets[index].x); else textWidth += (spriteFont.charRecs[index].width + spriteFont.charOffsets[index].x);
} }
@ -517,7 +517,7 @@ static int GetCharIndex(SpriteFont font, int letter)
#define UNORDERED_CHARSET #define UNORDERED_CHARSET
#if defined(UNORDERED_CHARSET) #if defined(UNORDERED_CHARSET)
int index = 0; int index = 0;
for (int i = 0; i < font.numChars; i++) for (int i = 0; i < font.numChars; i++)
{ {
if (font.charValues[i] == letter) if (font.charValues[i] == letter)
@ -526,7 +526,7 @@ static int GetCharIndex(SpriteFont font, int letter)
break; break;
} }
} }
return index; return index;
#else #else
return (letter - 32); return (letter - 32);
@ -607,14 +607,14 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
} }
TraceLog(DEBUG, "SpriteFont data parsed correctly from image"); TraceLog(DEBUG, "SpriteFont data parsed correctly from image");
// NOTE: We need to remove key color borders from image to avoid weird
// NOTE: We need to remove key color borders from image to avoid weird
// artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR // artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR
for (int i = 0; i < image.height*image.width; i++) if (COLOR_EQUAL(pixels[i], key)) pixels[i] = BLANK; for (int i = 0; i < image.height*image.width; i++) if (COLOR_EQUAL(pixels[i], key)) pixels[i] = BLANK;
// Create a new image with the processed color data (key color replaced by BLANK) // Create a new image with the processed color data (key color replaced by BLANK)
Image fontClear = LoadImageEx(pixels, image.width, image.height); Image fontClear = LoadImageEx(pixels, image.width, image.height);
free(pixels); // Free pixels array memory free(pixels); // Free pixels array memory
// Create spritefont with all data parsed from image // Create spritefont with all data parsed from image
@ -622,7 +622,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
spriteFont.numChars = index; spriteFont.numChars = index;
UnloadImage(fontClear); // Unload processed image once converted to texture UnloadImage(fontClear); // Unload processed image once converted to texture
// We got tempCharValues and tempCharsRecs populated with chars data // We got tempCharValues and tempCharsRecs populated with chars data
@ -643,7 +643,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
} }
spriteFont.size = spriteFont.charRecs[0].height; spriteFont.size = spriteFont.charRecs[0].height;
TraceLog(INFO, "Image file loaded correctly as SpriteFont"); TraceLog(INFO, "Image file loaded correctly as SpriteFont");
return spriteFont; return spriteFont;
@ -853,13 +853,13 @@ static SpriteFont LoadBMFont(const char *fileName)
strncat(texPath, texFileName, strlen(texFileName)); strncat(texPath, texFileName, strlen(texFileName));
TraceLog(DEBUG, "[%s] Font texture loading path: %s", fileName, texPath); TraceLog(DEBUG, "[%s] Font texture loading path: %s", fileName, texPath);
Image imFont = LoadImage(texPath); Image imFont = LoadImage(texPath);
if (imFont.format == UNCOMPRESSED_GRAYSCALE)
if (imFont.format == UNCOMPRESSED_GRAYSCALE)
{ {
Image imCopy = ImageCopy(imFont); Image imCopy = ImageCopy(imFont);
for (int i = 0; i < imCopy.width*imCopy.height; i++) ((unsigned char *)imCopy.data)[i] = 0xff; // WHITE pixel for (int i = 0; i < imCopy.width*imCopy.height; i++) ((unsigned char *)imCopy.data)[i] = 0xff; // WHITE pixel
ImageAlphaMask(&imCopy, imFont); ImageAlphaMask(&imCopy, imFont);
@ -867,7 +867,7 @@ static SpriteFont LoadBMFont(const char *fileName)
UnloadImage(imCopy); UnloadImage(imCopy);
} }
else font.texture = LoadTextureFromImage(imFont); else font.texture = LoadTextureFromImage(imFont);
font.size = fontSize; font.size = fontSize;
font.numChars = numChars; font.numChars = numChars;
font.charValues = (int *)malloc(numChars*sizeof(int)); font.charValues = (int *)malloc(numChars*sizeof(int));
@ -876,7 +876,7 @@ static SpriteFont LoadBMFont(const char *fileName)
font.charAdvanceX = (int *)malloc(numChars*sizeof(int)); font.charAdvanceX = (int *)malloc(numChars*sizeof(int));
UnloadImage(imFont); UnloadImage(imFont);
free(texPath); free(texPath);
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX; int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;
@ -913,11 +913,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int
// NOTE: Font texture size is predicted (being as much conservative as possible) // NOTE: Font texture size is predicted (being as much conservative as possible)
// Predictive method consist of supposing same number of chars by line-column (sqrtf) // Predictive method consist of supposing same number of chars by line-column (sqrtf)
// and a maximum character width of 3/4 of fontSize... it worked ok with all my tests... // and a maximum character width of 3/4 of fontSize... it worked ok with all my tests...
// Calculate next power-of-two value // Calculate next power-of-two value
float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)numChars)); float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)numChars));
int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT
TraceLog(INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize); TraceLog(INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize);
unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25); unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25);
@ -935,7 +935,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int
} }
fread(ttfBuffer, 1, 1 << 25, ttfFile); fread(ttfBuffer, 1, 1 << 25, ttfFile);
if (fontChars[0] != 32) TraceLog(WARNING, "TTF spritefont loading: first character is not SPACE(32) character"); if (fontChars[0] != 32) TraceLog(WARNING, "TTF spritefont loading: first character is not SPACE(32) character");
// NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image... // NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image...
@ -945,7 +945,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int
//if (result > 0) TraceLog(INFO, "TTF spritefont loading: first unused row of generated bitmap: %i", result); //if (result > 0) TraceLog(INFO, "TTF spritefont loading: first unused row of generated bitmap: %i", result);
if (result < 0) TraceLog(WARNING, "TTF spritefont loading: Not all the characters fit in the font"); if (result < 0) TraceLog(WARNING, "TTF spritefont loading: Not all the characters fit in the font");
free(ttfBuffer); free(ttfBuffer);
// Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA // Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA
@ -966,11 +966,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int
image.mipmaps = 1; image.mipmaps = 1;
image.format = UNCOMPRESSED_GRAY_ALPHA; image.format = UNCOMPRESSED_GRAY_ALPHA;
image.data = dataGrayAlpha; image.data = dataGrayAlpha;
font.texture = LoadTextureFromImage(image); font.texture = LoadTextureFromImage(image);
//SavePNG("generated_ttf_image.png", (unsigned char *)image.data, image.width, image.height, 2); //SavePNG("generated_ttf_image.png", (unsigned char *)image.data, image.width, image.height, 2);
UnloadImage(image); // Unloads dataGrayAlpha UnloadImage(image); // Unloads dataGrayAlpha
font.size = fontSize; font.size = fontSize;

+ 26
- 26
src/textures.c Ver arquivo

@ -144,9 +144,9 @@ Image LoadImage(const char *fileName)
else if (strcmp(GetExtension(fileName),"rres") == 0) else if (strcmp(GetExtension(fileName),"rres") == 0)
{ {
RRESData rres = LoadResource(fileName); RRESData rres = LoadResource(fileName);
// NOTE: Parameters for RRES_IMAGE type are: width, height, format, mipmaps // NOTE: Parameters for RRES_IMAGE type are: width, height, format, mipmaps
if (rres.type == RRES_IMAGE) image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); if (rres.type == RRES_IMAGE) image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3);
else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName); else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName);
@ -197,9 +197,9 @@ Image LoadImagePro(void *data, int width, int height, int format)
srcImage.height = height; srcImage.height = height;
srcImage.mipmaps = 1; srcImage.mipmaps = 1;
srcImage.format = format; srcImage.format = format;
Image dstImage = ImageCopy(srcImage); Image dstImage = ImageCopy(srcImage);
return dstImage; return dstImage;
} }
@ -244,7 +244,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
if (bytes < size) if (bytes < size)
{ {
TraceLog(WARNING, "[%s] RAW image data can not be read, wrong requested format or size", fileName); TraceLog(WARNING, "[%s] RAW image data can not be read, wrong requested format or size", fileName);
if (image.data != NULL) free(image.data); if (image.data != NULL) free(image.data);
} }
else else
@ -615,12 +615,12 @@ void ImageAlphaMask(Image *image, Image alphaMask)
// Force mask to be Grayscale // Force mask to be Grayscale
Image mask = ImageCopy(alphaMask); Image mask = ImageCopy(alphaMask);
if (mask.format != UNCOMPRESSED_GRAYSCALE) ImageFormat(&mask, UNCOMPRESSED_GRAYSCALE); if (mask.format != UNCOMPRESSED_GRAYSCALE) ImageFormat(&mask, UNCOMPRESSED_GRAYSCALE);
// In case image is only grayscale, we just add alpha channel // In case image is only grayscale, we just add alpha channel
if (image->format == UNCOMPRESSED_GRAYSCALE) if (image->format == UNCOMPRESSED_GRAYSCALE)
{ {
ImageFormat(image, UNCOMPRESSED_GRAY_ALPHA); ImageFormat(image, UNCOMPRESSED_GRAY_ALPHA);
// Apply alpha mask to alpha channel // Apply alpha mask to alpha channel
for (int i = 0, k = 1; (i < mask.width*mask.height) || (i < image->width*image->height); i++, k += 2) for (int i = 0, k = 1; (i < mask.width*mask.height) || (i < image->width*image->height); i++, k += 2)
{ {
@ -955,7 +955,7 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight)
void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
{ {
bool cropRequired = false; bool cropRequired = false;
// Security checks to avoid size and rectangle issues (out of bounds) // Security checks to avoid size and rectangle issues (out of bounds)
// Check that srcRec is inside src image // Check that srcRec is inside src image
if (srcRec.x < 0) srcRec.x = 0; if (srcRec.x < 0) srcRec.x = 0;
@ -973,15 +973,15 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
TraceLog(WARNING, "Source rectangle height out of bounds, rescaled height: %i", srcRec.height); TraceLog(WARNING, "Source rectangle height out of bounds, rescaled height: %i", srcRec.height);
cropRequired = true; cropRequired = true;
} }
Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it
ImageCrop(&srcCopy, srcRec); // Crop source image to desired source rectangle ImageCrop(&srcCopy, srcRec); // Crop source image to desired source rectangle
// Check that dstRec is inside dst image // Check that dstRec is inside dst image
// TODO: Allow negative position within destination with cropping // TODO: Allow negative position within destination with cropping
if (dstRec.x < 0) dstRec.x = 0; if (dstRec.x < 0) dstRec.x = 0;
if (dstRec.y < 0) dstRec.y = 0; if (dstRec.y < 0) dstRec.y = 0;
// Scale source image in case destination rec size is different than source rec size // Scale source image in case destination rec size is different than source rec size
if ((dstRec.width != srcRec.width) || (dstRec.height != srcRec.height)) if ((dstRec.width != srcRec.width) || (dstRec.height != srcRec.height))
{ {
@ -1001,20 +1001,20 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
TraceLog(WARNING, "Destination rectangle height out of bounds, rescaled height: %i", dstRec.height); TraceLog(WARNING, "Destination rectangle height out of bounds, rescaled height: %i", dstRec.height);
cropRequired = true; cropRequired = true;
} }
if (cropRequired) if (cropRequired)
{ {
// Crop destination rectangle if out of bounds // Crop destination rectangle if out of bounds
Rectangle crop = { 0, 0, dstRec.width, dstRec.height }; Rectangle crop = { 0, 0, dstRec.width, dstRec.height };
ImageCrop(&srcCopy, crop); ImageCrop(&srcCopy, crop);
} }
// Get image data as Color pixels array to work with it // Get image data as Color pixels array to work with it
Color *dstPixels = GetImageData(*dst); Color *dstPixels = GetImageData(*dst);
Color *srcPixels = GetImageData(srcCopy); Color *srcPixels = GetImageData(srcCopy);
UnloadImage(srcCopy); // Source copy not required any more... UnloadImage(srcCopy); // Source copy not required any more...
Color srcCol, dstCol; Color srcCol, dstCol;
// Blit pixels, copy source image into destination // Blit pixels, copy source image into destination
@ -1026,13 +1026,13 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
// Alpha blending implementation // Alpha blending implementation
dstCol = dstPixels[j*dst->width + i]; dstCol = dstPixels[j*dst->width + i];
srcCol = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)]; srcCol = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)];
dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r; dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r;
dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g; dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g;
dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b; dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b;
dstPixels[j*dst->width + i] = dstCol; dstPixels[j*dst->width + i] = dstCol;
// TODO: Support other blending options // TODO: Support other blending options
} }
} }
@ -1369,7 +1369,7 @@ void SetTextureFilter(Texture2D texture, int filterMode)
{ {
// RL_FILTER_MIP_NEAREST - tex filter: POINT, mipmaps filter: POINT (sharp switching between mipmaps) // RL_FILTER_MIP_NEAREST - tex filter: POINT, mipmaps filter: POINT (sharp switching between mipmaps)
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_NEAREST); rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_NEAREST);
// RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps // RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST); rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST);
} }
@ -1387,7 +1387,7 @@ void SetTextureFilter(Texture2D texture, int filterMode)
// RL_FILTER_LINEAR_MIP_NEAREST - tex filter: BILINEAR, mipmaps filter: POINT (sharp switching between mipmaps) // RL_FILTER_LINEAR_MIP_NEAREST - tex filter: BILINEAR, mipmaps filter: POINT (sharp switching between mipmaps)
// Alternative: RL_FILTER_NEAREST_MIP_LINEAR - tex filter: POINT, mipmaps filter: BILINEAR (smooth transition between mipmaps) // Alternative: RL_FILTER_NEAREST_MIP_LINEAR - tex filter: POINT, mipmaps filter: BILINEAR (smooth transition between mipmaps)
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR_MIP_NEAREST); rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR_MIP_NEAREST);
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
} }
@ -1404,14 +1404,14 @@ void SetTextureFilter(Texture2D texture, int filterMode)
{ {
// RL_FILTER_MIP_LINEAR - tex filter: BILINEAR, mipmaps filter: BILINEAR (smooth transition between mipmaps) // RL_FILTER_MIP_LINEAR - tex filter: BILINEAR, mipmaps filter: BILINEAR (smooth transition between mipmaps)
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR); rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR);
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
} }
else else
{ {
TraceLog(WARNING, "[TEX ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id); TraceLog(WARNING, "[TEX ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id);
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR); rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR);
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR); rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
@ -2007,19 +2007,19 @@ static Image LoadPVR(const char *fileName)
image.mipmaps = pvrHeader.numMipmaps; image.mipmaps = pvrHeader.numMipmaps;
// Check data format // Check data format
if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 0)) && (pvrHeader.channelDepth[0] == 8)) if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 0)) && (pvrHeader.channelDepth[0] == 8))
image.format = UNCOMPRESSED_GRAYSCALE; image.format = UNCOMPRESSED_GRAYSCALE;
else if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 'a')) && ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8))) else if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 'a')) && ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8)))
image.format = UNCOMPRESSED_GRAY_ALPHA; image.format = UNCOMPRESSED_GRAY_ALPHA;
else if ((pvrHeader.channels[0] == 'r') && (pvrHeader.channels[1] == 'g') && (pvrHeader.channels[2] == 'b')) else if ((pvrHeader.channels[0] == 'r') && (pvrHeader.channels[1] == 'g') && (pvrHeader.channels[2] == 'b'))
{ {
if (pvrHeader.channels[3] == 'a') if (pvrHeader.channels[3] == 'a')
{ {
if ((pvrHeader.channelDepth[0] == 5) && (pvrHeader.channelDepth[1] == 5) && (pvrHeader.channelDepth[2] == 5) && (pvrHeader.channelDepth[3] == 1)) if ((pvrHeader.channelDepth[0] == 5) && (pvrHeader.channelDepth[1] == 5) && (pvrHeader.channelDepth[2] == 5) && (pvrHeader.channelDepth[3] == 1))
image.format = UNCOMPRESSED_R5G5B5A1; image.format = UNCOMPRESSED_R5G5B5A1;
else if ((pvrHeader.channelDepth[0] == 4) && (pvrHeader.channelDepth[1] == 4) && (pvrHeader.channelDepth[2] == 4) && (pvrHeader.channelDepth[3] == 4)) else if ((pvrHeader.channelDepth[0] == 4) && (pvrHeader.channelDepth[1] == 4) && (pvrHeader.channelDepth[2] == 4) && (pvrHeader.channelDepth[3] == 4))
image.format = UNCOMPRESSED_R4G4B4A4; image.format = UNCOMPRESSED_R4G4B4A4;
else if ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8) && (pvrHeader.channelDepth[2] == 8) && (pvrHeader.channelDepth[3] == 8)) else if ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8) && (pvrHeader.channelDepth[2] == 8) && (pvrHeader.channelDepth[3] == 8))
image.format = UNCOMPRESSED_R8G8B8A8; image.format = UNCOMPRESSED_R8G8B8A8;
} }
else if (pvrHeader.channels[3] == 0) else if (pvrHeader.channels[3] == 0)

||||||
x
 
000:0
Carregando…
Cancelar
Salvar