1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#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;
}
|