#include "util.h"
#include <SDL2/SDL.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
unsigned int Util_Hash( const char *str )
{
unsigned int hash, i, length;
length = strlen(str);
for(hash = i = 0; i < length; ++i)
{
hash += str[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
void Util_FatalError( const char *fmt, ... )
{
fprintf(stderr, "Fatal Error:\n");
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
SDL_Quit();
exit(1);
}
void Util_CheckGLError()
{
GLenum error = glGetError();
switch(error)
{
case GL_INVALID_ENUM:
fprintf(stderr, "WARNING: GL_INVALID_ENUM\n");
break;
case GL_INVALID_VALUE:
fprintf(stderr, "WARNING: GL_INVALID_VALUE\n");
break;
case GL_INVALID_OPERATION:
fprintf(stderr, "WARNING: GL_INVALID_OPERATION\n");
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
fprintf(stderr, "WARNING: GL_INVALID_FRAMEBUFFER_OPERATION\n");
break;
case GL_OUT_OF_MEMORY:
fprintf(stderr, "WARNING: GL_OUT_OF_MEMORY\n");
break;
case GL_STACK_UNDERFLOW:
fprintf(stderr, "WARNING: GL_STACK_UNDERFLOW\n");
break;
case GL_STACK_OVERFLOW:
fprintf(stderr, "WARNING: GL_STACK_OVERFLOW\n");
break;
default:
break;
}
}
char *Util_LoadFile( const char *path )
{
FILE* file = fopen( path, "r" );
if(file == NULL)
{
Util_FatalError("File %s could not be found!\n", path);
}
fseek( file, 0, SEEK_END );
size_t sizeOfFile = ftell( file );
fseek( file, 0, SEEK_SET );
char* file_data = malloc( sizeof(char) * sizeOfFile + 1 );
fread( file_data, sizeof(char), sizeOfFile, file );
file_data[sizeOfFile] = '\0';
fclose(file);
return file_data;
}
float Util_RandomF(float min, float max)
{
return ( min + (float)rand() ) / ( (float)RAND_MAX / (max-min) );
}
int Util_RandomI(int min, int max)
{
return ( rand() % (max-min) ) + min;
}
Vec3
Util_GetMouseRay(int screenWidth, int screenHeigth, Mat4 *viewMatrix, Mat4 *projectionMatrix,
int mouseX, int mouseY)
{
Vec4 eyeCoords;
Vec3 mouseRay;
/* Normalized device coords NOTE: -y becouse for SDL y = 0 is the top of the screen */
GLfloat normalX = ( 2.0f * (GLfloat)mouseX ) / (GLfloat) screenWidth - 1.0f;
GLfloat normalY = 1.0f - (2.0f * (GLfloat)mouseY) / (GLfloat) screenHeigth;
/* clipCoords include 4th component */
Vec4 clipCoords = { normalX, normalY, -1.0f, 1.0f };
/* Remove perpective */
{
Mat4 invertedProjection = mat4_inverse(projectionMatrix);
eyeCoords = mat4_mul_vec4(&invertedProjection, &clipCoords);
eyeCoords.z = -1.0f;
eyeCoords.w = 0.0f;
}
/* Remove view matrix*/
{
Mat4 invertedViewMatrix = mat4_inverse(viewMatrix);
Vec4 temp = mat4_mul_vec4(&invertedViewMatrix, &eyeCoords);
mouseRay.x = temp.x;
mouseRay.y = temp.y;
mouseRay.z = temp.z;
mouseRay = vec3_normalize(&mouseRay);
}
/* Return the ray in world coordinates */
return mouseRay;
}