Big batch of changes! Check description:

Support multiple texture formats (uncompressed and compressed)
Postprocessing shaders support
Model struct redefined and improved
Extended loading functions for Textures and Models
Simplified functions: DrawPlane(), DrawQuad()
Deleted functions: DrawPlaneEx(), DrawGizmoEx()
Now Text module only depends on Textures module
Shapes: Reviewed functions to low lines/triangles usage
Removed useless tabs and spaces around code
This commit is contained in:
raysan5 2015-04-06 14:02:29 +02:00
parent 2b4a1f295a
commit a632a04a30
9 changed files with 662 additions and 723 deletions

View file

@ -267,7 +267,6 @@ static bool cameraUseGravity = true;
// Shaders variables // Shaders variables
static bool enabledPostpro = false; static bool enabledPostpro = false;
static unsigned int fboShader = 0;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by core) // Other Modules Functions Declaration (required by core)
@ -327,7 +326,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition);
// Initialize Window and Graphics Context (OpenGL) // Initialize Window and Graphics Context (OpenGL)
void InitWindow(int width, int height, const char *title) void InitWindow(int width, int height, const char *title)
{ {
TraceLog(INFO, "Initializing raylib (v1.2.2)"); TraceLog(INFO, "Initializing raylib (v1.3.0)");
// Store window title (could be useful...) // Store window title (could be useful...)
windowTitle = title; windowTitle = title;
@ -366,7 +365,7 @@ void InitWindow(int width, int height, const char *title)
// Android activity initialization // Android activity initialization
void InitWindow(int width, int height, struct android_app *state) void InitWindow(int width, int height, struct android_app *state)
{ {
TraceLog(INFO, "Initializing raylib (v1.2.2)"); TraceLog(INFO, "Initializing raylib (v1.3.0)");
app_dummy(); app_dummy();
@ -555,8 +554,7 @@ void EndDrawing(void)
{ {
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
// TODO: Set postprocessing shader to be passed: SetPostproShader()? if (enabledPostpro) rlglDrawPostpro(); // Draw postprocessing effect (shader)
if (enabledPostpro) rlglDrawPostpro(fboShader); // Draw postprocessing effect (shader)
SwapBuffers(); // Copy back buffer to front buffer SwapBuffers(); // Copy back buffer to front buffer
PollInputEvents(); // Poll user events PollInputEvents(); // Poll user events
@ -1114,16 +1112,23 @@ Vector2 GetTouchPosition(void)
}*/ }*/
#endif #endif
void InitPostShader(void) // Set postprocessing shader
void SetPostproShader(Shader shader)
{ {
rlglInitPostpro(); if (rlGetVersion() == OPENGL_11) TraceLog(WARNING, "Postprocessing shaders not supported on OpenGL 1.1");
else
enabledPostpro = true; {
} if (!enabledPostpro)
{
void SetPostShader(unsigned int shader) enabledPostpro = true;
{ rlglInitPostpro();
fboShader = shader; rlglSetPostproShader(shader);
}
else
{
rlglSetPostproShader(shader);
}
}
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View file

@ -444,48 +444,17 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
rlPopMatrix(); rlPopMatrix();
} }
// Draw a quad
void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4])
{
rlBegin(RL_QUADS);
rlColor4ub(colors[0].r, colors[0].g, colors[0].b, colors[0].a);
rlNormal3f(normals[0].x, normals[0].y, normals[0].z);
rlTexCoord2f(textcoords[0].x, textcoords[0].y);
rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
rlColor4ub(colors[1].r, colors[1].g, colors[1].b, colors[1].a);
rlNormal3f(normals[1].x, normals[1].y, normals[1].z);
rlTexCoord2f(textcoords[1].x, textcoords[1].y);
rlVertex3f(vertices[1].x, vertices[1].y, vertices[1].z);
rlColor4ub(colors[2].r, colors[2].g, colors[2].b, colors[2].a);
rlNormal3f(normals[2].x, normals[2].y, normals[2].z);
rlTexCoord2f(textcoords[2].x, textcoords[2].y);
rlVertex3f(vertices[2].x, vertices[2].y, vertices[2].z);
rlColor4ub(colors[3].r, colors[3].g, colors[3].b, colors[3].a);
rlNormal3f(normals[3].x, normals[3].y, normals[3].z);
rlTexCoord2f(textcoords[3].x, textcoords[3].y);
rlVertex3f(vertices[3].x, vertices[3].y, vertices[3].z);
rlEnd();
}
// Draw a plane // Draw a plane
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color) void DrawPlane(Vector3 centerPos, Vector2 size, Color color)
{ {
// NOTE: QUADS usage require defining a texture on OpenGL 3.3+ // NOTE: QUADS usage require defining a texture on OpenGL 3.3+
if (rlGetVersion() != OPENGL_11) rlEnableTexture(whiteTexture); // Default white texture if (rlGetVersion() != OPENGL_11) rlEnableTexture(whiteTexture); // Default white texture
// NOTE: Plane is always created on XZ ground and then rotated // NOTE: Plane is always created on XZ ground
rlPushMatrix(); rlPushMatrix();
rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
rlScalef(size.x, 1.0f, size.y); rlScalef(size.x, 1.0f, size.y);
// TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
rlRotatef(rotation.x, 1, 0, 0);
rlRotatef(rotation.y, 0, 1, 0);
rlRotatef(rotation.z, 0, 0, 1);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlNormal3f(0.0f, 1.0f, 0.0f); rlNormal3f(0.0f, 1.0f, 0.0f);
@ -499,53 +468,23 @@ void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
if (rlGetVersion() != OPENGL_11) rlDisableTexture(); if (rlGetVersion() != OPENGL_11) rlDisableTexture();
} }
// Draw a plane with divisions // Draw a quad
// TODO: Test this function void DrawQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Color color)
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color)
{ {
float quadWidth = size.x / slicesX; // TODO: Calculate normals from vertex position
float quadLenght = size.y / slicesZ;
float texPieceW = 1 / size.x; rlBegin(RL_QUADS);
float texPieceH = 1 / size.y; rlColor4ub(color.r, color.g, color.b, color.a);
//rlNormal3f(0.0f, 0.0f, 0.0f);
// NOTE: Plane is always created on XZ ground and then rotated rlVertex3f(v1.x, v1.y, v1.z);
rlPushMatrix(); rlVertex3f(v2.x, v2.y, v2.z);
rlTranslatef(-size.x / 2, 0.0f, -size.y / 2); rlVertex3f(v3.x, v3.y, v3.z);
rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlVertex3f(v4.x, v4.y, v4.z);
rlEnd();
// TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
rlRotatef(rotation.x, 1, 0, 0);
rlRotatef(rotation.y, 0, 1, 0);
rlRotatef(rotation.z, 0, 0, 1);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
rlNormal3f(0.0f, 1.0f, 0.0f);
for (int z = 0; z < slicesZ; z++)
{
for (int x = 0; x < slicesX; x++)
{
// Draw the plane quad by quad (with textcoords)
rlTexCoord2f((float)x * texPieceW, (float)z * texPieceH);
rlVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght);
rlTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH);
rlVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght);
rlTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH + texPieceH);
rlVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
rlTexCoord2f((float)x * texPieceW, (float)z * texPieceH + texPieceH);
rlVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
}
}
rlEnd();
rlPopMatrix();
} }
// Draw a ray line
void DrawRay(Ray ray, Color color) void DrawRay(Ray ray, Color color)
{ {
float scale = 10000; float scale = 10000;
@ -615,76 +554,7 @@ void DrawGizmo(Vector3 position)
rlPopMatrix(); rlPopMatrix();
} }
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale) // Load a 3d model (from file)
{
// NOTE: RGB = XYZ
rlPushMatrix();
rlTranslatef(position.x, position.y, position.z);
rlScalef(scale, scale, scale);
rlRotatef(rotation.y, 0, 1, 0);
rlBegin(RL_LINES);
// X Axis
rlColor4ub(200, 0, 0, 255); rlVertex3f(position.x, position.y, position.z);
rlColor4ub(200, 0, 0, 255); rlVertex3f(position.x + 1, position.y, position.z);
// ArrowX
rlColor4ub(200, 0, 0, 255); rlVertex3f(position.x + 1.1, position.y, position.z);
rlColor4ub(200, 0, 0, 255); rlVertex3f(position.x + .9, position.y, position.z + .1);
rlColor4ub(200, 0, 0, 255); rlVertex3f(position.x + 1.1, position.y, position.z);
rlColor4ub(200, 0, 0, 255); rlVertex3f(position.x + .9, position.y, position.z - .1);
// Y Axis
rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x, position.y, position.z);
rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x, position.y + 1, position.z);
// ArrowY
rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x, position.y + 1.1, position.z);
rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x + .1, position.y + .9, position.z);
rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x, position.y + 1.1, position.z);
rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x - .1, position.y + .9, position.z);
// Z Axis
rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x, position.y, position.z);
rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x, position.y, position.z - 1);
// ArrowZ
rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x, position.y, position.z - 1.1);
rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x + .1, position.y, position.z - .9);
rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x, position.y, position.z - 1.1);
rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x - .1, position.y, position.z - .9);
// Extra
int n = 3;
// X Axis
for (int i=0; i < 360; i += 6)
{
rlColor4ub(200, 0, 0, 255); rlVertex3f(0, position.x + sin(DEG2RAD*i) * scale/n, position.y + cos(DEG2RAD*i) * scale/n);
rlColor4ub(200, 0, 0, 255); rlVertex3f(0, position.x + sin(DEG2RAD*(i+6)) * scale/n, position.y + cos(DEG2RAD*(i+6)) * scale/n);
}
// Y Axis
for (int i=0; i < 360; i += 6)
{
rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x + sin(DEG2RAD*i) * scale/n, 0, position.y + cos(DEG2RAD*i) * scale/n);
rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x + sin(DEG2RAD*(i+6)) * scale/n, 0, position.y + cos(DEG2RAD*(i+6)) * scale/n);
}
// Z Axis
for (int i=0; i < 360; i += 6)
{
rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x + sin(DEG2RAD*i) * scale/n, position.y + cos(DEG2RAD*i) * scale/n, 0);
rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x + sin(DEG2RAD*(i+6)) * scale/n, position.y + cos(DEG2RAD*(i+6)) * scale/n, 0);
}
rlEnd();
rlPopMatrix();
}
// Load a 3d model
Model LoadModel(const char *fileName) Model LoadModel(const char *fileName)
{ {
VertexData vData; VertexData vData;
@ -694,6 +564,7 @@ Model LoadModel(const char *fileName)
// NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct // NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct
// NOTE: model properties (transform, texture, shader) are initialized inside rlglLoadModel()
Model model = rlglLoadModel(vData); // Upload vertex data to GPU Model model = rlglLoadModel(vData); // Upload vertex data to GPU
// Now that vertex data is uploaded to GPU, we can free arrays // Now that vertex data is uploaded to GPU, we can free arrays
@ -708,6 +579,19 @@ Model LoadModel(const char *fileName)
return model; return model;
} }
// Load a 3d model (from vertex data)
Model LoadModelEx(VertexData data)
{
Model model;
// NOTE: model properties (transform, texture, shader) are initialized inside rlglLoadModel()
model = rlglLoadModel(data); // Upload vertex data to GPU
// NOTE: Vertex data is managed externally, must be deallocated manually
return model;
}
// Load a heightmap image as a 3d model // Load a heightmap image as a 3d model
Model LoadHeightmap(Image heightmap, float maxHeight) Model LoadHeightmap(Image heightmap, float maxHeight)
{ {
@ -847,7 +731,7 @@ Model LoadCubicmap(Image cubesmap)
float w = mapCubeSide; float w = mapCubeSide;
float h = mapCubeSide; float h = mapCubeSide;
float h2 = mapCubeSide * 1.5; // TODO: Review walls height... float h2 = mapCubeSide * 1.5; // TODO: Review walls height...
Vector3 *mapVertices = (Vector3 *)malloc(maxTriangles * 3 * sizeof(Vector3)); Vector3 *mapVertices = (Vector3 *)malloc(maxTriangles * 3 * sizeof(Vector3));
Vector2 *mapTexcoords = (Vector2 *)malloc(maxTriangles * 3 * sizeof(Vector2)); Vector2 *mapTexcoords = (Vector2 *)malloc(maxTriangles * 3 * sizeof(Vector2));
@ -1208,11 +1092,11 @@ void UnloadModel(Model model)
free(model.mesh.normals); free(model.mesh.normals);
} }
rlDeleteBuffers(model.vboId[0]); rlDeleteBuffers(model.mesh.vboId[0]);
rlDeleteBuffers(model.vboId[1]); rlDeleteBuffers(model.mesh.vboId[1]);
rlDeleteBuffers(model.vboId[2]); rlDeleteBuffers(model.mesh.vboId[2]);
rlDeleteVertexArrays(model.vaoId); rlDeleteVertexArrays(model.mesh.vaoId);
rlDeleteTextures(model.texture.id); rlDeleteTextures(model.texture.id);
rlDeleteShader(model.shader.id); rlDeleteShader(model.shader.id);
} }
@ -1227,17 +1111,15 @@ void SetModelTexture(Model *model, Texture2D texture)
void DrawModel(Model model, Vector3 position, float scale, Color tint) void DrawModel(Model model, Vector3 position, float scale, Color tint)
{ {
Vector3 vScale = { scale, scale, scale }; Vector3 vScale = { scale, scale, scale };
float rotAngle = 0.0f; Vector3 rotationAxis = { 0, 0, 0 };
Vector3 rotAxis = { 0, 0, 0 };
rlglDrawModel(model, position, rotAngle, rotAxis, vScale, tint, false); DrawModelEx(model, position, 0.0f, rotationAxis, vScale, tint);
} }
// Draw a model with extended parameters // Draw a model with extended parameters
void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint) void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint)
{ {
// NOTE: Rotation must be provided in degrees, it's converted to radians inside rlglDrawModel() // NOTE: Rotation must be provided in degrees, it's converted to radians inside rlglDrawModel()
rlglDrawModel(model, position, rotationAngle, rotationAxis, scale, tint, false); rlglDrawModel(model, position, rotationAngle, rotationAxis, scale, tint, false);
} }
@ -1245,10 +1127,9 @@ void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rot
void DrawModelWires(Model model, Vector3 position, float scale, Color color) void DrawModelWires(Model model, Vector3 position, float scale, Color color)
{ {
Vector3 vScale = { scale, scale, scale }; Vector3 vScale = { scale, scale, scale };
float rotAngle = 0.0f; Vector3 rotationAxis = { 0, 0, 0 };
Vector3 rotAxis = { 0, 0, 0 };
rlglDrawModel(model, position, rotAngle, rotAxis, vScale, color, true); rlglDrawModel(model, position, 0.0f, rotationAxis, vScale, color, true);
} }
// Draw a billboard // Draw a billboard

View file

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raylib 1.2 (www.raylib.com) * raylib 1.3.0 (www.raylib.com)
* *
* A simple and easy-to-use library to learn videogames programming * A simple and easy-to-use library to learn videogames programming
* *
@ -199,6 +199,14 @@ typedef struct Vector3 {
float z; float z;
} Vector3; } Vector3;
// Matrix type (OpenGL style 4x4 - right handed, column major)
typedef struct Matrix {
float m0, m4, m8, m12;
float m1, m5, m9, m13;
float m2, m6, m10, m14;
float m3, m7, m11, m15;
} Matrix;
// Color type, RGBA (32bit) // Color type, RGBA (32bit)
typedef struct Color { typedef struct Color {
unsigned char r; unsigned char r;
@ -258,12 +266,15 @@ typedef struct Camera {
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
// Vertex data definning a mesh // Vertex data definning a mesh
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
typedef struct VertexData { typedef struct VertexData {
int vertexCount; int vertexCount;
float *vertices; // 3 components per vertex float *vertices; // 3 components per vertex
float *texcoords; // 2 components per vertex float *texcoords; // 2 components per vertex
float *normals; // 3 components per vertex float *normals; // 3 components per vertex
unsigned char *colors; // 4 components per vertex unsigned char *colors; // 4 components per vertex
unsigned int vaoId;
unsigned int vboId[4];
} VertexData; } VertexData;
// Shader type // Shader type
@ -284,14 +295,11 @@ typedef struct Shader {
} Shader; } Shader;
// 3d Model type // 3d Model type
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
typedef struct Model { typedef struct Model {
VertexData mesh; VertexData mesh;
unsigned int vaoId; Matrix transform;
unsigned int vboId[4];
Texture2D texture; Texture2D texture;
Shader shader; Shader shader;
//Matrix transform;
} Model; } Model;
// Ray type (useful for raycast) // Ray type (useful for raycast)
@ -315,6 +323,24 @@ typedef struct Wave {
short channels; short channels;
} Wave; } Wave;
// Texture formats (support depends on OpenGL version)
typedef enum {
UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
UNCOMPRESSED_R5G6B5, // 16 bpp
UNCOMPRESSED_R8G8B8, // 24 bpp
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
UNCOMPRESSED_R8G8B8A8, // 32 bpp
COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
COMPRESSED_DXT3_RGBA, // 8 bpp
COMPRESSED_DXT5_RGBA, // 8 bpp
COMPRESSED_ETC1_RGB, // 4 bpp
COMPRESSED_ETC2_RGB, // 4 bpp
COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
/*COMPRESSED_ASTC_RGBA_4x4*/ // 8 bpp
} TextureFormat;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { // Prevents name mangling of functions extern "C" { // Prevents name mangling of functions
#endif #endif
@ -366,8 +392,7 @@ Camera UpdateCamera(Vector3 *position); // Update camera wit
void SetConfigFlags(char flags); // Enable some window configurations void SetConfigFlags(char flags); // Enable some window configurations
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags) void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
void InitPostShader(void); // Initialize fullscreen postproduction shaders system void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
void SetPostShader(unsigned int shader); // Set fullscreen postproduction shader
Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Gives the rayTrace from mouse position Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Gives the rayTrace from mouse position
@ -448,6 +473,7 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2
Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps); // Load a texture from raw data into GPU memory
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
Texture2D LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps) Texture2D LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps)
Texture2D CreateTexture(Image image, bool genMipmaps); // [DEPRECATED] Same as LoadTextureFromImage() Texture2D CreateTexture(Image image, bool genMipmaps); // [DEPRECATED] Same as LoadTextureFromImage()
@ -490,19 +516,18 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4]); // Draw a quad void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane void DrawQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Color color); // Draw a quad
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions void DrawRay(Ray ray, Color color); // Draw a ray line
void DrawRay(Ray ray, Color color);
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
void DrawGizmo(Vector3 position); // Draw simple gizmo void DrawGizmo(Vector3 position); // Draw simple gizmo
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale); // Draw gizmo with extended parameters
//DrawTorus(), DrawTeapot() are useless... //DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Model 3d Loading and Drawing Functions (Module: models) // Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
Model LoadModelEx(VertexData data); // Load a 3d model (from vertex data)
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource) //Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
@ -517,7 +542,7 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color color);
void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader (vertex shader + fragment shader) Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader (vertex shader + fragment shader)
bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB);
bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2); bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2);

View file

@ -53,15 +53,15 @@
float y; float y;
float z; float z;
} Vector3; } Vector3;
#endif
// Matrix type (OpenGL style 4x4 - right handed, column major) // Matrix type (OpenGL style 4x4 - right handed, column major)
typedef struct Matrix { typedef struct Matrix {
float m0, m4, m8, m12; float m0, m4, m8, m12;
float m1, m5, m9, m13; float m1, m5, m9, m13;
float m2, m6, m10, m14; float m2, m6, m10, m14;
float m3, m7, m11, m15; float m3, m7, m11, m15;
} Matrix; } Matrix;
#endif
// Quaternion type // Quaternion type
typedef struct Quaternion { typedef struct Quaternion {

View file

@ -63,6 +63,28 @@
#define TEMP_VERTEX_BUFFER_SIZE 4096 // Temporal Vertex Buffer (required for vertex-transformations) #define TEMP_VERTEX_BUFFER_SIZE 4096 // Temporal Vertex Buffer (required for vertex-transformations)
// NOTE: Every vertex are 3 floats (12 bytes) // NOTE: Every vertex are 3 floats (12 bytes)
#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif
#ifndef GL_ETC1_RGB8_OES
#define GL_ETC1_RGB8_OES 0x8D64
#endif
#ifndef GL_COMPRESSED_RGB8_ETC2
#define GL_COMPRESSED_RGB8_ETC2 0x9274
#endif
#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -174,7 +196,8 @@ static bool useTempBuffer = false;
static bool vaoSupported = false; static bool vaoSupported = false;
// Framebuffer object and texture // Framebuffer object and texture
static GLuint fbo, fboColorTexture, fboDepthTexture, fboShader = 0; static GLuint fbo, fboColorTexture, fboDepthTexture;
static Model postproQuad;
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
@ -199,6 +222,7 @@ static Shader LoadSimpleShader(void);
static void InitializeBuffers(void); static void InitializeBuffers(void);
static void InitializeBuffersGPU(void); static void InitializeBuffersGPU(void);
static void UpdateBuffers(void); static void UpdateBuffers(void);
static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat);
// Custom shader files loading (external) // Custom shader files loading (external)
static char *TextFileRead(char *fn); static char *TextFileRead(char *fn);
@ -688,18 +712,21 @@ void rlDeleteTextures(unsigned int id)
glDeleteTextures(1, &id); glDeleteTextures(1, &id);
} }
// Enable rendering to postprocessing FBO
void rlEnableFBO(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
#endif
}
// Unload shader from GPU memory // Unload shader from GPU memory
void rlDeleteShader(unsigned int id) void rlDeleteShader(unsigned int id)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glDeleteProgram(id); glDeleteProgram(id);
}
void rlEnableFBO(void)
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
}
#endif #endif
}
// Unload vertex data (VAO) from GPU memory // Unload vertex data (VAO) from GPU memory
void rlDeleteVertexArrays(unsigned int id) void rlDeleteVertexArrays(unsigned int id)
@ -840,7 +867,18 @@ void rlglInit(void)
TraceLog(INFO, "Supported extension: %s", extensions); TraceLog(INFO, "Supported extension: %s", extensions);
#endif #endif
*/ */
/*
GLint numComp = 0;
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numComp);
GLint format[32] = { 0 };
glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, format);
for (int i = 0; i < numComp; i++)
{
TraceLog(INFO, "Supported compressed format: 0x%x", format[i]);
}
*/
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Set default draw mode // Set default draw mode
currentDrawMode = RL_TRIANGLES; currentDrawMode = RL_TRIANGLES;
@ -869,7 +907,7 @@ void rlglInit(void)
// Create default white texture for plain colors (required by shader) // Create default white texture for plain colors (required by shader)
unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes)
whiteTexture = rlglLoadTexture(pixels, 1, 1, R8G8B8A8, false); whiteTexture = rlglLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1, false);
if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture loaded successfully", whiteTexture); if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture loaded successfully", whiteTexture);
else TraceLog(WARNING, "Base white texture could not be loaded"); else TraceLog(WARNING, "Base white texture could not be loaded");
@ -888,10 +926,10 @@ void rlglInit(void)
#endif #endif
} }
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Init postpro system // Init postpro system
void rlglInitPostpro(void) void rlglInitPostpro(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Create the texture that will serve as the color attachment for the framebuffer // Create the texture that will serve as the color attachment for the framebuffer
glGenTextures(1, &fboColorTexture); glGenTextures(1, &fboColorTexture);
glBindTexture(GL_TEXTURE_2D, fboColorTexture); glBindTexture(GL_TEXTURE_2D, fboColorTexture);
@ -927,11 +965,42 @@ void rlglInitPostpro(void)
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
fboShader = 0; // Create a simple quad model to render fbo texture
VertexData quadData;
// TODO: Init simple quad VAO and data here? quadData.vertexCount = 6;
}
float w = GetScreenWidth();
float h = GetScreenHeight();
float quadPositions[6*3] = { w, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, h, 0.0, 0, h, 0.0, w, h, 0.0, w, 0.0, 0.0 };
float quadTexcoords[6*2] = { 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0 };
float quadNormals[6*3] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0 };
unsigned char quadColors[6*4] = { 255 };
quadData.vertices = quadPositions;
quadData.texcoords = quadTexcoords;
quadData.normals = quadNormals;
quadData.colors = quadColors;
postproQuad = rlglLoadModel(quadData);
Texture2D texture;
texture.id = fboColorTexture;
texture.width = w;
texture.height = h;
SetModelTexture(&postproQuad, texture);
#endif #endif
}
// Set postprocessing shader
void rlglSetPostproShader(Shader shader)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
SetModelShader(&postproQuad, shader);
#endif
}
// Vertex Buffer Object deinitialization (memory free) // Vertex Buffer Object deinitialization (memory free)
void rlglClose(void) void rlglClose(void)
@ -988,7 +1057,12 @@ void rlglClose(void)
// Free GPU texture // Free GPU texture
glDeleteTextures(1, &whiteTexture); glDeleteTextures(1, &whiteTexture);
if (fbo != 0) glDeleteFramebuffers(1, &fbo); if (fbo != 0)
{
glDeleteFramebuffers(1, &fbo);
UnloadModel(postproQuad);
}
free(draws); free(draws);
#endif #endif
@ -1142,68 +1216,15 @@ void rlglDraw(void)
#endif #endif
} }
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Draw with postprocessing shader
void rlglDrawPostpro(unsigned int shaderId) void rlglDrawPostpro(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
// TODO: Draw screen quad with texture rlglDrawModel(postproQuad, (Vector3){0,0,0}, 0.0f, (Vector3){0,0,0}, (Vector3){1.0f, 1.0f, 1.0f}, WHITE, false);
/*
const float quadPositions[] = { 1.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, -1.0, 0.0,
-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0 };
const float quadTexcoords[] = { 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0 };
glBindBuffer(GL_ARRAY_BUFFER, quadVbo);
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), quadPositions);
glVertexAttribPointer(ATTRIB_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), quadTexcoords);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_TEXCOORD0);
glBindTexture(GL_TEXTURE_2D, fboColorTexture);
glDrawArrays(GL_TRIANGLES, 0, 2*3);
// Quad render using triangle strip
glBindBuffer(GL_ARRAY_BUFFER, uiVBO[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);
*/
rlEnableTexture(fboColorTexture);
rlPushMatrix();
rlBegin(RL_QUADS);
rlColor4ub(255, 255, 255, 255);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
// Bottom-left corner for texture and quad
rlTexCoord2f(0.0f, 1.0f);
rlVertex2f(0.0f, 0.0f);
// Bottom-right corner for texture and quad
rlTexCoord2f(0.0f, 0.0f);
rlVertex2f(0.0f, GetScreenHeight());
// Top-right corner for texture and quad
rlTexCoord2f(1.0f, 0.0f);
rlVertex2f(GetScreenWidth(), GetScreenHeight());
// Top-left corner for texture and quad
rlTexCoord2f(1.0f, 1.0f);
rlVertex2f(GetScreenWidth(), 0.0f);
rlEnd();
rlPopMatrix();
fboShader = shaderId;
rlglDraw();
}
#endif #endif
}
// Draw a 3d model // Draw a 3d model
void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires) void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires)
@ -1250,7 +1271,9 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(model.shader.id); glUseProgram(model.shader.id);
Vector3 rotation = { 0.0f, 0.0f, 0.0f }; // TODO: Use model.transform matrix
Vector3 rotation = { 0.0f, 0.0f, 0.0f };
// Get transform matrix (rotation -> scale -> translation) // Get transform matrix (rotation -> scale -> translation)
Matrix transform = MatrixTransform(position, rotation, scale); // Object-space transformation Matrix transform = MatrixTransform(position, rotation, scale); // Object-space transformation
@ -1271,21 +1294,21 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
if (vaoSupported) if (vaoSupported)
{ {
glBindVertexArray(model.vaoId); glBindVertexArray(model.mesh.vaoId);
} }
else else
{ {
// Bind model VBOs data // Bind model VBOs data
glBindBuffer(GL_ARRAY_BUFFER, model.vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, model.mesh.vboId[0]);
glVertexAttribPointer(model.shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(model.shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(model.shader.vertexLoc); glEnableVertexAttribArray(model.shader.vertexLoc);
glBindBuffer(GL_ARRAY_BUFFER, model.vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, model.mesh.vboId[1]);
glVertexAttribPointer(model.shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(model.shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(model.shader.texcoordLoc); glEnableVertexAttribArray(model.shader.texcoordLoc);
// Add normals support // Add normals support
glBindBuffer(GL_ARRAY_BUFFER, model.vboId[2]); glBindBuffer(GL_ARRAY_BUFFER, model.mesh.vboId[2]);
glVertexAttribPointer(model.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(model.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(model.shader.normalLoc); glEnableVertexAttribArray(model.shader.normalLoc);
} }
@ -1512,23 +1535,41 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
return rayWorld; return rayWorld;
*/ */
return (Vector3){ 0, 0, 0 };
} }
// Convert image data to OpenGL texture (returns OpenGL valid Id) // Convert image data to OpenGL texture (returns OpenGL valid Id)
unsigned int rlglLoadTexture(unsigned char *data, int width, int height, int colorMode, bool genMipmaps) unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps)
{ {
glBindTexture(GL_TEXTURE_2D,0); // Free any old binding glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding
GLuint id; GLuint id;
glGenTextures(1, &id); // Generate Pointer to the texture
// TODO: Review compressed textures support by OpenGL version
/* (rlGetVersion() == OPENGL_11)
if ((textureFormat == COMPRESSED_DXT1_RGB) || (textureFormat == COMPRESSED_DXT3_RGBA) || (textureFormat == COMPRESSED_DXT5_RGBA) ||
(textureFormat == COMPRESSED_ETC1_RGB8) || (textureFormat == COMPRESSED_ETC2_RGB8) || (textureFormat == COMPRESSED_ETC2_EAC_RGBA8))
{
id = 0;
TraceLog(WARNING, "GPU compressed textures not supported on OpenGL 1.1");
return id;
}
*/
glGenTextures(1, &id); // Generate Pointer to the texture
//glActiveTexture(GL_TEXTURE0); //glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, id); glBindTexture(GL_TEXTURE_2D, id);
// NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used! // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used!
#if defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Set texture to clamp on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Set texture to clamp on y-axis
#else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis
#endif
bool texIsPOT = false; bool texIsPOT = false;
@ -1542,6 +1583,8 @@ unsigned int rlglLoadTexture(unsigned char *data, int width, int height, int col
genMipmaps = false; genMipmaps = false;
} }
// TODO: Support mipmaps --> if (mipmapCount > 1)
// If mipmaps are being used, we configure mag-min filters accordingly // If mipmaps are being used, we configure mag-min filters accordingly
// NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so only GL_LINEAR or GL_NEAREST can be used // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so only GL_LINEAR or GL_NEAREST can be used
if (genMipmaps) if (genMipmaps)
@ -1587,35 +1630,76 @@ unsigned int rlglLoadTexture(unsigned char *data, int width, int height, int col
else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
#endif #endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33)
// NOTE: We define internal (GPU) format as GL_RGBA8 (probably BGRA8 in practice, driver takes care) // NOTE: We define internal (GPU) format as GL_RGBA8 (probably BGRA8 in practice, driver takes care)
// NOTE: On embedded systems, we let the driver choose the best internal format // NOTE: On embedded systems, we let the driver choose the best internal format
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // OpenGL
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // WebGL
// TODO: Add support for multiple color modes (16bit color modes and grayscale) // Support for multiple color modes (16bit color modes and grayscale)
// Ref: https://www.khronos.org/opengles/sdk/docs/man3/html/glTexImage2D.xhtml
// On WebGL, internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA
// (sized)internalFormat format type // (sized)internalFormat format type
// GL_R GL_RED GL_UNSIGNED_BYTE // GL_R GL_RED GL_UNSIGNED_BYTE
// GL_RGB565 GL_RGB GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5 // GL_RGB565 GL_RGB GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5
// GL_RGB5_A1 GL_RGBA GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_5_5_1 // GL_RGB5_A1 GL_RGBA GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_5_5_1
// GL_RGBA4 GL_RGBA GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_4_4_4_4 // GL_RGBA4 GL_RGBA GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_4_4_4_4
// GL_RGBA8 GL_RGBA GL_UNSIGNED_BYTE // GL_RGBA8 GL_RGBA GL_UNSIGNED_BYTE
// GL_RGB8 GL_RGB GL_UNSIGNED_BYTE // GL_RGB8 GL_RGB GL_UNSIGNED_BYTE
switch (colorMode) switch (textureFormat)
{ {
case GRAYSCALE: glTexImage2D(GL_TEXTURE_2D, 0, GL_R, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, data); break; case UNCOMPRESSED_GRAYSCALE:
case R5G6B5: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); break; {
case R8G8B8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); break; glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, (unsigned char *)data);
case R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, data); break;
case R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); break; // With swizzleMask we define how a one channel texture will be mapped to RGBA
case R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break; // Required GL >= 3.3 or EXT_texture_swizzle/ARB_texture_swizzle
default: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break; GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, 1.0f };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
TraceLog(INFO, "Grayscale texture loaded and swizzled!");
} break;
case UNCOMPRESSED_R5G6B5: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (unsigned short *)data); break;
case UNCOMPRESSED_R8G8B8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break;
case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break;
case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
case COMPRESSED_DXT1_RGB: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT1_RGBA: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT3_RGBA: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break;
case COMPRESSED_DXT5_RGBA: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); break;
case COMPRESSED_ETC1_RGB: TraceLog(WARNING, "ETC compression not supported"); break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3
case COMPRESSED_ETC2_RGB: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB8_ETC2); break;//TraceLog(WARNING, "ETC compression not supported"); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
case COMPRESSED_ETC2_EAC_RGBA: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA8_ETC2_EAC); break;//TraceLog(WARNING, "ETC compression not supported"); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
//case COMPRESSED_ASTC_RGBA_4x4: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_4x4_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
default: TraceLog(WARNING, "Texture format not recognized"); break;
} }
if (genMipmaps) if ((mipmapCount == 1) && (genMipmaps))
{
glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically for new texture", id);
}
#elif defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA
switch (textureFormat)
{
case UNCOMPRESSED_GRAYSCALE: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
case UNCOMPRESSED_R5G6B5: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (unsigned short *)data); break;
case UNCOMPRESSED_R8G8B8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break;
case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break;
case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
case COMPRESSED_DXT1_RGB: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT1_RGBA: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT3_RGBA: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break; // NOTE: Not supported by WebGL
case COMPRESSED_DXT5_RGBA: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); break; // NOTE: Not supported by WebGL
case COMPRESSED_ETC1_RGB: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_ETC1_RGB8_OES); break;
case COMPRESSED_ETC2_RGB: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB8_ETC2); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
case COMPRESSED_ETC2_EAC_RGBA: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA8_ETC2_EAC); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
//case COMPRESSED_ASTC_RGBA_4x4: LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_4x4_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
default: TraceLog(WARNING, "Texture format not recognized"); break;
}
if ((mipmapCount == 1) && (genMipmaps))
{ {
glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically for new texture", id); TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically for new texture", id);
@ -1638,13 +1722,15 @@ Model rlglLoadModel(VertexData mesh)
Model model; Model model;
model.mesh = mesh; model.mesh = mesh;
model.transform = MatrixIdentity();
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
model.mesh.vaoId = 0; // Vertex Array Object
model.mesh.vboId[0] = 0; // Vertex position VBO
model.mesh.vboId[1] = 0; // Texcoords VBO
model.mesh.vboId[2] = 0; // Normals VBO
model.texture.id = 0; // No texture required model.texture.id = 0; // No texture required
model.vaoId = 0; // Vertex Array Object model.shader.id = 0; // No shader used
model.vboId[0] = 0; // Vertex position VBO
model.vboId[1] = 0; // Texcoords VBO
model.vboId[2] = 0; // Normals VBO
#elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
model.texture.id = whiteTexture; // Default whiteTexture model.texture.id = whiteTexture; // Default whiteTexture
@ -1684,106 +1770,28 @@ Model rlglLoadModel(VertexData mesh)
model.shader = simpleShader; // By default, simple shader will be used model.shader = simpleShader; // By default, simple shader will be used
model.vboId[0] = vertexBuffer[0]; // Vertex position VBO model.mesh.vboId[0] = vertexBuffer[0]; // Vertex position VBO
model.vboId[1] = vertexBuffer[1]; // Texcoords VBO model.mesh.vboId[1] = vertexBuffer[1]; // Texcoords VBO
model.vboId[2] = vertexBuffer[2]; // Normals VBO model.mesh.vboId[2] = vertexBuffer[2]; // Normals VBO
if (vaoSupported) if (vaoSupported)
{ {
if (vaoModel > 0) if (vaoModel > 0)
{ {
model.vaoId = vaoModel; model.mesh.vaoId = vaoModel;
TraceLog(INFO, "[VAO ID %i] Model uploaded successfully to VRAM (GPU)", vaoModel); TraceLog(INFO, "[VAO ID %i] Model uploaded successfully to VRAM (GPU)", vaoModel);
} }
else TraceLog(WARNING, "Model could not be uploaded to VRAM (GPU)"); else TraceLog(WARNING, "Model could not be uploaded to VRAM (GPU)");
} }
else else
{ {
TraceLog(INFO, "[VBO ID %i][VBO ID %i][VBO ID %i] Model uploaded successfully to VRAM (GPU)", model.vboId[0], model.vboId[1], model.vboId[2]); TraceLog(INFO, "[VBO ID %i][VBO ID %i][VBO ID %i] Model uploaded successfully to VRAM (GPU)", model.mesh.vboId[0], model.mesh.vboId[1], model.mesh.vboId[2]);
} }
#endif #endif
return model; return model;
} }
// Convert image data to OpenGL texture (returns OpenGL valid Id)
// NOTE: Expected compressed image data and POT image
unsigned int rlglLoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compFormat)
{
GLuint id;
#if defined(GRAPHICS_API_OPENGL_11)
id = 0;
TraceLog(WARNING, "GPU compressed textures not supported on OpenGL 1.1");
#elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
TraceLog(DEBUG, "Compressed texture width: %i", width);
TraceLog(DEBUG, "Compressed texture height: %i", height);
TraceLog(DEBUG, "Compressed texture mipmap levels: %i", mipmapCount);
TraceLog(DEBUG, "Compressed texture format: 0x%x", compFormat);
if (compFormat == 0)
{
id = 0;
TraceLog(WARNING, "Texture compressed format not recognized", id);
}
else
{
glGenTextures(1, &id);
// Bind the texture
glBindTexture(GL_TEXTURE_2D, id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Set texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// If mipmaps are being used, we configure mag-min filters accordingly
if (mipmapCount > 1)
{
// Trilinear filtering with mipmaps
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate use of mipmaps (must be available)
}
else
{
// Not using mipmappings
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
}
int blockSize = 0;
int offset = 0;
if (compFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) blockSize = 8;
else blockSize = 16;
// Load the mipmaps
for (int level = 0; level < mipmapCount && (width || height); level++)
{
unsigned int size = 0;
// NOTE: size specifies the number of bytes of image data (S3TC/DXTC)
if (compFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) size = ((width + 3)/4)*((height + 3)/4)*blockSize; // S3TC/DXTC
#if defined(GRAPHICS_API_OPENGL_ES2)
else if (compFormat == GL_ETC1_RGB8_OES) size = 8*((width + 3) >> 2)*((height + 3) >> 2); // ETC1
#endif
glCompressedTexImage2D(GL_TEXTURE_2D, level, compFormat, width, height, 0, size, data + offset);
offset += size;
width /= 2;
height /= 2;
// Security check for NPOT textures
if (width < 1) width = 1;
if (height < 1) height = 1;
}
}
#endif
return id;
}
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Load a shader (vertex shader + fragment shader) from text data // Load a shader (vertex shader + fragment shader) from text data
@ -1907,12 +1915,12 @@ unsigned char *rlglReadScreenPixels(int width, int height)
return imgData; // NOTE: image data should be freed return imgData; // NOTE: image data should be freed
} }
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Load a shader (vertex shader + fragment shader) from text data // Load a shader (vertex shader + fragment shader) from text data
Shader LoadShader(char *vsFileName, char *fsFileName) Shader LoadShader(char *vsFileName, char *fsFileName)
{ {
Shader shader; Shader shader;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Shaders loading from external text file // Shaders loading from external text file
char *vShaderStr = TextFileRead(vsFileName); char *vShaderStr = TextFileRead(vsFileName);
char *fShaderStr = TextFileRead(fsFileName); char *fShaderStr = TextFileRead(fsFileName);
@ -1941,6 +1949,7 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
shader.textureLoc = glGetUniformLocation(shader.id, "texture0"); shader.textureLoc = glGetUniformLocation(shader.id, "texture0");
shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor"); shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor");
//-------------------------------------------------------------------- //--------------------------------------------------------------------
#endif
return shader; return shader;
} }
@ -1948,28 +1957,31 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
// Link shader to model // Link shader to model
void SetModelShader(Model *model, Shader shader) void SetModelShader(Model *model, Shader shader)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
model->shader = shader; model->shader = shader;
if (vaoSupported) glBindVertexArray(model->vaoId); if (vaoSupported) glBindVertexArray(model->mesh.vaoId);
// Enable vertex attributes: position // Enable vertex attributes: position
glBindBuffer(GL_ARRAY_BUFFER, model->vboId[0]); glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[0]);
glEnableVertexAttribArray(shader.vertexLoc); glEnableVertexAttribArray(shader.vertexLoc);
glVertexAttribPointer(shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
// Enable vertex attributes: texcoords // Enable vertex attributes: texcoords
glBindBuffer(GL_ARRAY_BUFFER, model->vboId[1]); glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[1]);
glEnableVertexAttribArray(shader.texcoordLoc); glEnableVertexAttribArray(shader.texcoordLoc);
glVertexAttribPointer(shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
// Enable vertex attributes: normals // Enable vertex attributes: normals
glBindBuffer(GL_ARRAY_BUFFER, model->vboId[2]); glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[2]);
glEnableVertexAttribArray(shader.normalLoc); glEnableVertexAttribArray(shader.normalLoc);
glVertexAttribPointer(shader.normalLoc, 3, GL_FLOAT, 0, 0, 0); glVertexAttribPointer(shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
if (vaoSupported) glBindVertexArray(0); // Unbind VAO if (vaoSupported) glBindVertexArray(0); // Unbind VAO
#endif
} }
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
void PrintProjectionMatrix() void PrintProjectionMatrix()
{ {
PrintMatrix(projection); PrintMatrix(projection);
@ -1979,7 +1991,6 @@ void PrintModelviewMatrix()
{ {
PrintMatrix(modelview); PrintMatrix(modelview);
} }
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1987,6 +1998,41 @@ void PrintModelviewMatrix()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Convert image data to OpenGL texture (returns OpenGL valid Id)
// NOTE: Expected compressed image data and POT image
static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
int blockSize = 0; // Bytes every block
int offset = 0;
if ((compressedFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) ||
(compressedFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ||
#if defined(GRAPHICS_API_OPENGL_ES2)
(compressedFormat == GL_ETC1_RGB8_OES) ||
#endif
(compressedFormat == GL_COMPRESSED_RGB8_ETC2)) blockSize = 8;
else blockSize = 16;
// Load the mipmap levels
for (int level = 0; level < mipmapCount && (width || height); level++)
{
unsigned int size = 0;
size = ((width + 3)/4)*((height + 3)/4)*blockSize;
glCompressedTexImage2D(GL_TEXTURE_2D, level, compressedFormat, width, height, 0, size, data + offset);
offset += size;
width /= 2;
height /= 2;
// Security check for NPOT textures
if (width < 1) width = 1;
if (height < 1) height = 1;
}
}
// Load Shader (Vertex and Fragment) // Load Shader (Vertex and Fragment)
// NOTE: This shader program is used only for batch buffers (lines, triangles, quads) // NOTE: This shader program is used only for batch buffers (lines, triangles, quads)
@ -2000,7 +2046,7 @@ static Shader LoadDefaultShader(void)
// Vertex shader directly defined, no external file required // Vertex shader directly defined, no external file required
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
char vShaderStr[] = " #version 330 \n" // NOTE: Actually, #version 110 (quivalent to #version 100 on ES2) char vShaderStr[] = " #version 110 \n" // NOTE: Actually, #version 110 (quivalent to #version 100 on ES2)
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
char vShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work! char vShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work!
#endif #endif
@ -2020,7 +2066,7 @@ static Shader LoadDefaultShader(void)
// Fragment shader directly defined, no external file required // Fragment shader directly defined, no external file required
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
char fShaderStr[] = " #version 330 \n" // NOTE: Actually, #version 110 (quivalent to #version 100 on ES2) char fShaderStr[] = " #version 110 \n" // NOTE: Actually, #version 110 (quivalent to #version 100 on ES2)
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
char fShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work! char fShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work!
"precision mediump float; \n" // WebGL, required for emscripten "precision mediump float; \n" // WebGL, required for emscripten

View file

@ -88,25 +88,37 @@ typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
typedef enum { GRAYSCALE = 0, R5G6B5, R8G8B8, R5G5B5A1, R4G4B4A4, R8G8B8A8 } ColorMode;
#ifdef RLGL_STANDALONE #ifdef RLGL_STANDALONE
// Texture formats (support depends on OpenGL version)
typedef enum {
UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
UNCOMPRESSED_R5G6B5, // 16 bpp
UNCOMPRESSED_R8G8B8, // 24 bpp
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
UNCOMPRESSED_R8G8B8A8, // 32 bpp
COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
COMPRESSED_DXT3_RGBA, // 8 bpp
COMPRESSED_DXT5_RGBA, // 8 bpp
COMPRESSED_ETC1_RGB, // 4 bpp
COMPRESSED_ETC2_RGB, // 4 bpp
COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
/*COMPRESSED_ASTC_RGBA_4x4*/ // 8 bpp
} TextureFormat;
// VertexData type // VertexData type
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
typedef struct VertexData { typedef struct VertexData {
int vertexCount; int vertexCount;
float *vertices; // 3 components per vertex float *vertices; // 3 components per vertex
float *texcoords; // 2 components per vertex float *texcoords; // 2 components per vertex
float *normals; // 3 components per vertex float *normals; // 3 components per vertex
unsigned char *colors; unsigned char *colors;
unsigned int vaoId;
unsigned int vboId[4];
} VertexData; } VertexData;
// Texture2D type
typedef struct Texture2D {
unsigned int id; // Texture id
int width;
int height;
} Texture2D;
// Shader type // Shader type
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
@ -125,15 +137,19 @@ typedef enum { GRAYSCALE = 0, R5G6B5, R8G8B8, R5G5B5A1, R4G4B4A4, R8G8B8A8 } Col
} Shader; } Shader;
// 3d Model type // 3d Model type
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
typedef struct Model { typedef struct Model {
VertexData mesh; VertexData mesh;
unsigned int vaoId; Matrix transform;
unsigned int vboId[4];
Texture2D texture; Texture2D texture;
Shader shader; Shader shader;
//Matrix transform;
} Model; } Model;
// Texture2D type
typedef struct Texture2D {
unsigned int id; // Texture id
int width;
int height;
} Texture2D;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -181,28 +197,27 @@ void rlDeleteBuffers(unsigned int id); // Unload vertex data (VBO) from
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth) void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
int rlGetVersion(void); // Returns current OpenGL version int rlGetVersion(void); // Returns current OpenGL version
void rlEnableFBO(void); void rlEnableFBO(void); // Enable rendering to postprocessing FBO
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - rlgl functionality // Functions Declaration - rlgl functionality
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...) void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...)
void rlglInitPostpro(void); // Initialize postprocessing system
void rlglClose(void); // De-init rlgl void rlglClose(void); // De-init rlgl
void rlglDraw(void); // Draw VAO/VBO void rlglDraw(void); // Draw VAO/VBO
void rlglDrawPostpro(unsigned int shaderId); // Draw with postpro shader
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff) void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
unsigned int rlglLoadTexture(unsigned char *data, int width, int height, int colorMode, bool genMipmaps); // Load in GPU OpenGL texture unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps); // Load in GPU OpenGL texture
unsigned int rlglLoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int format); unsigned int rlglLoadShader(char *vShaderStr, char *fShaderStr); // Load a shader from text data
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) void rlglInitPostpro(void); // Initialize postprocessing system
unsigned int rlglLoadShader(char *vShaderStr, char *fShaderStr); // Load a shader from text data void rlglDrawPostpro(void); // Draw with postprocessing shader
#endif void rlglSetPostproShader(Shader shader); // Set postprocessing shader
Model rlglLoadModel(VertexData mesh); // Upload vertex data into GPU and provided VAO/VBO ids Model rlglLoadModel(VertexData mesh); // Upload vertex data into GPU and provided VAO/VBO ids
void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires); void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires);
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
byte *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) byte *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)

View file

@ -98,7 +98,7 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
// Draw a color-filled circle // Draw a color-filled circle
void DrawCircle(int centerX, int centerY, float radius, Color color) void DrawCircle(int centerX, int centerY, float radius, Color color)
{ {
DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color); DrawPoly((Vector2){ centerX, centerY }, 36, radius, 0, color);
} }
// Draw a gradient-filled circle // Draw a gradient-filled circle
@ -106,14 +106,14 @@ void DrawCircle(int centerX, int centerY, float radius, Color color)
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2) void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
{ {
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i=0; i < 360; i += 2) for (int i = 0; i < 360; i += 10)
{ {
rlColor4ub(color1.r, color1.g, color1.b, color1.a); rlColor4ub(color1.r, color1.g, color1.b, color1.a);
rlVertex2i(centerX, centerY); rlVertex2i(centerX, centerY);
rlColor4ub(color2.r, color2.g, color2.b, color2.a); rlColor4ub(color2.r, color2.g, color2.b, color2.a);
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius); rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
rlColor4ub(color2.r, color2.g, color2.b, color2.a); rlColor4ub(color2.r, color2.g, color2.b, color2.a);
rlVertex2f(centerX + sin(DEG2RAD*(i+2)) * radius, centerY + cos(DEG2RAD*(i+2)) * radius); rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius);
} }
rlEnd(); rlEnd();
} }
@ -122,12 +122,12 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
void DrawCircleV(Vector2 center, float radius, Color color) void DrawCircleV(Vector2 center, float radius, Color color)
{ {
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i=0; i < 360; i += 2) for (int i = 0; i < 360; i += 10)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(center.x, center.y); rlVertex2i(center.x, center.y);
rlVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius); rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
rlVertex2f(center.x + sin(DEG2RAD*(i+2)) * radius, center.y + cos(DEG2RAD*(i+2)) * radius); rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius);
} }
rlEnd(); rlEnd();
} }
@ -139,10 +139,10 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
// NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360) // NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
for (int i=0; i < 360; i++) for (int i = 0; i < 360; i += 10)
{ {
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius); rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
rlVertex2f(centerX + sin(DEG2RAD*(i+1)) * radius, centerY + cos(DEG2RAD*(i+1)) * radius); rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius);
} }
rlEnd(); rlEnd();
} }
@ -201,7 +201,7 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color)
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer rlNormal3f(0.0f, 0.0f, 1.0f);
rlTexCoord2f(0.0f, 0.0f); rlTexCoord2f(0.0f, 0.0f);
rlVertex2f(position.x, position.y); rlVertex2f(position.x, position.y);
@ -275,13 +275,13 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
rlRotatef(rotation, 0, 0, 1); rlRotatef(rotation, 0, 0, 1);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i=0; i < 360; i += 360/sides) for (int i = 0; i < 360; i += 360/sides)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(0, 0); rlVertex2i(0, 0);
rlVertex2f(sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius); rlVertex2f(sin(DEG2RAD*i)*radius, cos(DEG2RAD*i)*radius);
rlVertex2f(sin(DEG2RAD*(i+360/sides)) * radius, cos(DEG2RAD*(i+360/sides)) * radius); rlVertex2f(sin(DEG2RAD*(i + 360/sides))*radius, cos(DEG2RAD*(i + 360/sides))*radius);
} }
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();
@ -299,8 +299,8 @@ void DrawPolyEx(Vector2 *points, int numPoints, Color color)
for (int i = 0; i < numPoints - 2; i++) for (int i = 0; i < numPoints - 2; i++)
{ {
rlVertex2f(points[i].x, points[i].y); rlVertex2f(points[i].x, points[i].y);
rlVertex2f(points[i+1].x, points[i+1].y); rlVertex2f(points[i + 1].x, points[i + 1].y);
rlVertex2f(points[i+2].x, points[i+2].y); rlVertex2f(points[i + 2].x, points[i + 2].y);
} }
rlEnd(); rlEnd();
} }
@ -318,7 +318,7 @@ void DrawPolyExLines(Vector2 *points, int numPoints, Color color)
for (int i = 0; i < numPoints - 1; i++) for (int i = 0; i < numPoints - 1; i++)
{ {
rlVertex2f(points[i].x, points[i].y); rlVertex2f(points[i].x, points[i].y);
rlVertex2f(points[i+1].x, points[i+1].y); rlVertex2f(points[i + 1].x, points[i + 1].y);
} }
rlEnd(); rlEnd();
} }
@ -367,10 +367,10 @@ bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2)
{ {
bool collision = false; bool collision = false;
int dx = abs((rec1.x + rec1.width / 2) - (rec2.x + rec2.width / 2)); int dx = abs((rec1.x + rec1.width/2) - (rec2.x + rec2.width/2));
int dy = abs((rec1.y + rec1.height / 2) - (rec2.y + rec2.height / 2)); int dy = abs((rec1.y + rec1.height/2) - (rec2.y + rec2.height/2));
if ((dx <= (rec1.width / 2 + rec2.width / 2)) && ((dy <= (rec1.height / 2 + rec2.height / 2)))) collision = true; if ((dx <= (rec1.width/2 + rec2.width/2)) && ((dy <= (rec1.height/2 + rec2.height/2)))) collision = true;
return collision; return collision;
} }
@ -395,10 +395,10 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
{ {
bool collision = false; bool collision = false;
float dx = abs((rec.x + rec.width / 2) - center.x); float dx = abs((rec.x + rec.width/2) - center.x);
float dy = abs((rec.y + rec.height / 2) - center.y); float dy = abs((rec.y + rec.height/2) - center.y);
if ((dx <= (rec.width / 2 + radius)) && (dy <= (rec.height / 2 + radius))) collision = true; if ((dx <= (rec.width/2 + radius)) && (dy <= (rec.height/2 + radius))) collision = true;
return collision; return collision;
} }

View file

@ -30,10 +30,9 @@
#include <stdarg.h> // Used for functions with variable number of parameters (FormatText()) #include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
#include <stdio.h> // Standard input / output lib #include <stdio.h> // Standard input / output lib
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 #include "utils.h" // Required for function GetExtension()
#include "utils.h" // Required for function GetExtendion()
// Following libs will be used on LoadTTF() // Following libs are used on LoadTTF()
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#define STB_RECT_PACK_IMPLEMENTATION #define STB_RECT_PACK_IMPLEMENTATION
#include "stb_rect_pack.h" #include "stb_rect_pack.h"
@ -44,7 +43,7 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#define FONT_FIRST_CHAR 32 #define FONT_FIRST_CHAR 32
#define MAX_FONTCHARS 128 #define MAX_FONTCHARS 128
#define MAX_FORMATTEXT_LENGTH 50 #define MAX_FORMATTEXT_LENGTH 64
#define BIT_CHECK(a,b) ((a) & (1<<(b))) #define BIT_CHECK(a,b) ((a) & (1<<(b)))
@ -93,60 +92,60 @@ extern void LoadDefaultFont(void)
// This way, we reconstruct SpriteFont without creating large global variables // This way, we reconstruct SpriteFont without creating large global variables
// This data is automatically allocated to Stack and automatically deallocated at the end of this function // This data is automatically allocated to Stack and automatically deallocated at the end of this function
int defaultFontData[512] = { int defaultFontData[512] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200020, 0x0001b000, 0x00000000, 0x00000000, 0x8ef92520, 0x00020a00, 0x7dbe8000, 0x1f7df45f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200020, 0x0001b000, 0x00000000, 0x00000000, 0x8ef92520, 0x00020a00, 0x7dbe8000, 0x1f7df45f,
0x4a2bf2a0, 0x0852091e, 0x41224000, 0x10041450, 0x2e292020, 0x08220812, 0x41222000, 0x10041450, 0x10f92020, 0x3efa084c, 0x7d22103c, 0x107df7de, 0x4a2bf2a0, 0x0852091e, 0x41224000, 0x10041450, 0x2e292020, 0x08220812, 0x41222000, 0x10041450, 0x10f92020, 0x3efa084c, 0x7d22103c, 0x107df7de,
0xe8a12020, 0x08220832, 0x05220800, 0x10450410, 0xa4a3f000, 0x08520832, 0x05220400, 0x10450410, 0xe2f92020, 0x0002085e, 0x7d3e0281, 0x107df41f, 0xe8a12020, 0x08220832, 0x05220800, 0x10450410, 0xa4a3f000, 0x08520832, 0x05220400, 0x10450410, 0xe2f92020, 0x0002085e, 0x7d3e0281, 0x107df41f,
0x00200000, 0x8001b000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200000, 0x8001b000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0000fbe, 0xfbf7e00f, 0x5fbf7e7d, 0x0050bee8, 0x440808a2, 0x0a142fe8, 0x50810285, 0x0050a048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0000fbe, 0xfbf7e00f, 0x5fbf7e7d, 0x0050bee8, 0x440808a2, 0x0a142fe8, 0x50810285, 0x0050a048,
0x49e428a2, 0x0a142828, 0x40810284, 0x0048a048, 0x10020fbe, 0x09f7ebaf, 0xd89f3e84, 0x0047a04f, 0x09e48822, 0x0a142aa1, 0x50810284, 0x0048a048, 0x49e428a2, 0x0a142828, 0x40810284, 0x0048a048, 0x10020fbe, 0x09f7ebaf, 0xd89f3e84, 0x0047a04f, 0x09e48822, 0x0a142aa1, 0x50810284, 0x0048a048,
0x04082822, 0x0a142fa0, 0x50810285, 0x0050a248, 0x00008fbe, 0xfbf42021, 0x5f817e7d, 0x07d09ce8, 0x00008000, 0x00000fe0, 0x00000000, 0x00000000, 0x04082822, 0x0a142fa0, 0x50810285, 0x0050a248, 0x00008fbe, 0xfbf42021, 0x5f817e7d, 0x07d09ce8, 0x00008000, 0x00000fe0, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000c0180, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000c0180,
0xdfbf4282, 0x0bfbf7ef, 0x42850505, 0x004804bf, 0x50a142c6, 0x08401428, 0x42852505, 0x00a808a0, 0x50a146aa, 0x08401428, 0x42852505, 0x00081090, 0xdfbf4282, 0x0bfbf7ef, 0x42850505, 0x004804bf, 0x50a142c6, 0x08401428, 0x42852505, 0x00a808a0, 0x50a146aa, 0x08401428, 0x42852505, 0x00081090,
0x5fa14a92, 0x0843f7e8, 0x7e792505, 0x00082088, 0x40a15282, 0x08420128, 0x40852489, 0x00084084, 0x40a16282, 0x0842022a, 0x40852451, 0x00088082, 0x5fa14a92, 0x0843f7e8, 0x7e792505, 0x00082088, 0x40a15282, 0x08420128, 0x40852489, 0x00084084, 0x40a16282, 0x0842022a, 0x40852451, 0x00088082,
0xc0bf4282, 0xf843f42f, 0x7e85fc21, 0x3e0900bf, 0x00000000, 0x00000004, 0x00000000, 0x000c0180, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0bf4282, 0xf843f42f, 0x7e85fc21, 0x3e0900bf, 0x00000000, 0x00000004, 0x00000000, 0x000c0180, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000402, 0x41482000, 0x00000000, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000402, 0x41482000, 0x00000000, 0x00000800,
0x04000404, 0x4100203c, 0x00000000, 0x00000800, 0xf7df7df0, 0x514bef85, 0xbefbefbe, 0x04513bef, 0x14414500, 0x494a2885, 0xa28a28aa, 0x04510820, 0x04000404, 0x4100203c, 0x00000000, 0x00000800, 0xf7df7df0, 0x514bef85, 0xbefbefbe, 0x04513bef, 0x14414500, 0x494a2885, 0xa28a28aa, 0x04510820,
0xf44145f0, 0x474a289d, 0xa28a28aa, 0x04510be0, 0x14414510, 0x494a2884, 0xa28a28aa, 0x02910a00, 0xf7df7df0, 0xd14a2f85, 0xbefbe8aa, 0x011f7be0, 0xf44145f0, 0x474a289d, 0xa28a28aa, 0x04510be0, 0x14414510, 0x494a2884, 0xa28a28aa, 0x02910a00, 0xf7df7df0, 0xd14a2f85, 0xbefbe8aa, 0x011f7be0,
0x00000000, 0x00400804, 0x20080000, 0x00000000, 0x00000000, 0x00600f84, 0x20080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00400804, 0x20080000, 0x00000000, 0x00000000, 0x00600f84, 0x20080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xac000000, 0x00000f01, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x06000000, 0x24000000, 0x00000901, 0x00000000, 0x09108000, 0xac000000, 0x00000f01, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x06000000, 0x24000000, 0x00000901, 0x00000000, 0x09108000,
0x24fa28a2, 0x00000901, 0x00000000, 0x013e0000, 0x2242252a, 0x00000952, 0x00000000, 0x038a8000, 0x2422222a, 0x00000929, 0x00000000, 0x010a8000, 0x24fa28a2, 0x00000901, 0x00000000, 0x013e0000, 0x2242252a, 0x00000952, 0x00000000, 0x038a8000, 0x2422222a, 0x00000929, 0x00000000, 0x010a8000,
0x2412252a, 0x00000901, 0x00000000, 0x010a8000, 0x24fbe8be, 0x00000901, 0x00000000, 0x0ebe8000, 0xac020000, 0x00000f01, 0x00000000, 0x00048000, 0x2412252a, 0x00000901, 0x00000000, 0x010a8000, 0x24fbe8be, 0x00000901, 0x00000000, 0x0ebe8000, 0xac020000, 0x00000f01, 0x00000000, 0x00048000,
0x0003e000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, 0x8443b80e, 0x00203a03, 0x0003e000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, 0x8443b80e, 0x00203a03,
0x02bea080, 0xf0000020, 0xc452208a, 0x04202b02, 0xf8029122, 0x07f0003b, 0xe44b388e, 0x02203a02, 0x081e8a1c, 0x0411e92a, 0xf4420be0, 0x01248202, 0x02bea080, 0xf0000020, 0xc452208a, 0x04202b02, 0xf8029122, 0x07f0003b, 0xe44b388e, 0x02203a02, 0x081e8a1c, 0x0411e92a, 0xf4420be0, 0x01248202,
0xe8140414, 0x05d104ba, 0xe7c3b880, 0x00893a0a, 0x283c0e1c, 0x04500902, 0xc4400080, 0x00448002, 0xe8208422, 0x04500002, 0x80400000, 0x05200002, 0xe8140414, 0x05d104ba, 0xe7c3b880, 0x00893a0a, 0x283c0e1c, 0x04500902, 0xc4400080, 0x00448002, 0xe8208422, 0x04500002, 0x80400000, 0x05200002,
0x083e8e00, 0x04100002, 0x804003e0, 0x07000042, 0xf8008400, 0x07f00003, 0x80400000, 0x04000022, 0x00000000, 0x00000000, 0x80400000, 0x04000002, 0x083e8e00, 0x04100002, 0x804003e0, 0x07000042, 0xf8008400, 0x07f00003, 0x80400000, 0x04000022, 0x00000000, 0x00000000, 0x80400000, 0x04000002,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00800702, 0x1848a0c2, 0x84010000, 0x02920921, 0x01042642, 0x00005121, 0x42023f7f, 0x00291002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00800702, 0x1848a0c2, 0x84010000, 0x02920921, 0x01042642, 0x00005121, 0x42023f7f, 0x00291002,
0xefc01422, 0x7efdfbf7, 0xefdfa109, 0x03bbbbf7, 0x28440f12, 0x42850a14, 0x20408109, 0x01111010, 0x28440408, 0x42850a14, 0x2040817f, 0x01111010, 0xefc01422, 0x7efdfbf7, 0xefdfa109, 0x03bbbbf7, 0x28440f12, 0x42850a14, 0x20408109, 0x01111010, 0x28440408, 0x42850a14, 0x2040817f, 0x01111010,
0xefc78204, 0x7efdfbf7, 0xe7cf8109, 0x011111f3, 0x2850a932, 0x42850a14, 0x2040a109, 0x01111010, 0x2850b840, 0x42850a14, 0xefdfbf79, 0x03bbbbf7, 0xefc78204, 0x7efdfbf7, 0xe7cf8109, 0x011111f3, 0x2850a932, 0x42850a14, 0x2040a109, 0x01111010, 0x2850b840, 0x42850a14, 0xefdfbf79, 0x03bbbbf7,
0x001fa020, 0x00000000, 0x00001000, 0x00000000, 0x00002070, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x001fa020, 0x00000000, 0x00001000, 0x00000000, 0x00002070, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x08022800, 0x00012283, 0x02430802, 0x01010001, 0x8404147c, 0x20000144, 0x80048404, 0x00823f08, 0xdfbf4284, 0x7e03f7ef, 0x142850a1, 0x0000210a, 0x08022800, 0x00012283, 0x02430802, 0x01010001, 0x8404147c, 0x20000144, 0x80048404, 0x00823f08, 0xdfbf4284, 0x7e03f7ef, 0x142850a1, 0x0000210a,
0x50a14684, 0x528a1428, 0x142850a1, 0x03efa17a, 0x50a14a9e, 0x52521428, 0x142850a1, 0x02081f4a, 0x50a15284, 0x4a221428, 0xf42850a1, 0x03efa14b, 0x50a14684, 0x528a1428, 0x142850a1, 0x03efa17a, 0x50a14a9e, 0x52521428, 0x142850a1, 0x02081f4a, 0x50a15284, 0x4a221428, 0xf42850a1, 0x03efa14b,
0x50a16284, 0x4a521428, 0x042850a1, 0x0228a17a, 0xdfbf427c, 0x7e8bf7ef, 0xf7efdfbf, 0x03efbd0b, 0x00000000, 0x04000000, 0x00000000, 0x00000008, 0x50a16284, 0x4a521428, 0x042850a1, 0x0228a17a, 0xdfbf427c, 0x7e8bf7ef, 0xf7efdfbf, 0x03efbd0b, 0x00000000, 0x04000000, 0x00000000, 0x00000008,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200508, 0x00840400, 0x11458122, 0x00014210, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200508, 0x00840400, 0x11458122, 0x00014210,
0x00514294, 0x51420800, 0x20a22a94, 0x0050a508, 0x00200000, 0x00000000, 0x00050000, 0x08000000, 0xfefbefbe, 0xfbefbefb, 0xfbeb9114, 0x00fbefbe, 0x00514294, 0x51420800, 0x20a22a94, 0x0050a508, 0x00200000, 0x00000000, 0x00050000, 0x08000000, 0xfefbefbe, 0xfbefbefb, 0xfbeb9114, 0x00fbefbe,
0x20820820, 0x8a28a20a, 0x8a289114, 0x3e8a28a2, 0xfefbefbe, 0xfbefbe0b, 0x8a289114, 0x008a28a2, 0x228a28a2, 0x08208208, 0x8a289114, 0x088a28a2, 0x20820820, 0x8a28a20a, 0x8a289114, 0x3e8a28a2, 0xfefbefbe, 0xfbefbe0b, 0x8a289114, 0x008a28a2, 0x228a28a2, 0x08208208, 0x8a289114, 0x088a28a2,
0xfefbefbe, 0xfbefbefb, 0xfa2f9114, 0x00fbefbe, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0x00000000, 0x00000000, 0xfefbefbe, 0xfbefbefb, 0xfa2f9114, 0x00fbefbe, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00210100, 0x00000004, 0x00000000, 0x00000000, 0x14508200, 0x00001402, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00210100, 0x00000004, 0x00000000, 0x00000000, 0x14508200, 0x00001402, 0x00000000, 0x00000000,
0x00000010, 0x00000020, 0x00000000, 0x00000000, 0xa28a28be, 0x00002228, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022e8, 0x00000000, 0x00000000, 0x00000010, 0x00000020, 0x00000000, 0x00000000, 0xa28a28be, 0x00002228, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022e8, 0x00000000, 0x00000000,
0xa28a28aa, 0x000022a8, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022e8, 0x00000000, 0x00000000, 0xbefbefbe, 0x00003e2f, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022a8, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022e8, 0x00000000, 0x00000000, 0xbefbefbe, 0x00003e2f, 0x00000000, 0x00000000,
0x00000004, 0x00002028, 0x00000000, 0x00000000, 0x80000000, 0x00003e0f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00002028, 0x00000000, 0x00000000, 0x80000000, 0x00003e0f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
int charsHeight = 10; int charsHeight = 10;
int charsDivisor = 1; // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically int charsDivisor = 1; // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically
int charsWidth[224] = { 3, 1, 4, 6, 5, 7, 6, 2, 3, 3, 5, 5, 2, 4, 1, 7, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 3, 4, 3, 6, int charsWidth[224] = { 3, 1, 4, 6, 5, 7, 6, 2, 3, 3, 5, 5, 2, 4, 1, 7, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 3, 4, 3, 6,
7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 5, 6, 5, 7, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 6, 6, 6, 2, 7, 2, 3, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 5, 6, 5, 7, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 6, 6, 6, 2, 7, 2, 3, 5,
2, 5, 5, 5, 5, 5, 4, 5, 5, 1, 2, 5, 2, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 3, 1, 3, 4, 4, 2, 5, 5, 5, 5, 5, 4, 5, 5, 1, 2, 5, 2, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 3, 1, 3, 4, 4,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 5, 5, 5, 7, 1, 5, 3, 7, 3, 5, 4, 1, 7, 4, 3, 5, 3, 3, 2, 5, 6, 1, 2, 2, 3, 5, 6, 6, 6, 6, 1, 1, 5, 5, 5, 7, 1, 5, 3, 7, 3, 5, 4, 1, 7, 4, 3, 5, 3, 3, 2, 5, 6, 1, 2, 2, 3, 5, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 3, 3, 3, 3, 7, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 4, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 3, 3, 3, 3, 7, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 4, 6,
5, 5, 5, 5, 5, 5, 9, 5, 5, 5, 5, 5, 2, 2, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5 }; 5, 5, 5, 5, 5, 5, 9, 5, 5, 5, 5, 5, 2, 2, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5 };
// Re-construct image from defaultFontData and generate OpenGL texture // Re-construct image from defaultFontData and generate OpenGL texture
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -211,7 +210,7 @@ extern void LoadDefaultFont(void)
extern void UnloadDefaultFont(void) extern void UnloadDefaultFont(void)
{ {
rlDeleteTextures(defaultFont.texture.id); UnloadTexture(defaultFont.texture);
free(defaultFont.charSet); free(defaultFont.charSet);
} }
@ -258,7 +257,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
// Unload SpriteFont from GPU memory // Unload SpriteFont from GPU memory
void UnloadSpriteFont(SpriteFont spriteFont) void UnloadSpriteFont(SpriteFont spriteFont)
{ {
rlDeleteTextures(spriteFont.texture.id); UnloadTexture(spriteFont.texture);
free(spriteFont.charSet); free(spriteFont.charSet);
} }
@ -284,7 +283,7 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int fontSize, int spacing, Color tint) void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int fontSize, int spacing, Color tint)
{ {
int length = strlen(text); int length = strlen(text);
int positionX = (int)position.x; int offsetX = 0;
float scaleFactor; float scaleFactor;
unsigned char letter; unsigned char letter;
@ -293,45 +292,26 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int f
if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f; if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
else scaleFactor = (float)fontSize / spriteFont.charSet[0].h; else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
rlEnableTexture(spriteFont.texture.id); for(int i = 0; i < length; i++)
{
rlBegin(RL_QUADS); if ((unsigned char)text[i] == 0xc2)
for(int i = 0; i < length; i++)
{ {
if ((unsigned char)text[i] == 0xc2) letter = (unsigned char)text[i + 1];
{ c = spriteFont.charSet[letter - FONT_FIRST_CHAR];
letter = (unsigned char)text[i + 1]; i++;
c = spriteFont.charSet[letter - FONT_FIRST_CHAR];
i++;
}
else if ((unsigned char)text[i] == 0xc3)
{
letter = (unsigned char)text[i + 1];
c = spriteFont.charSet[letter - FONT_FIRST_CHAR + 64];
i++;
}
else c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR];
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
rlTexCoord2f((float)c.x / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);
rlVertex2f(positionX, position.y);
rlTexCoord2f((float)c.x / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);
rlVertex2f(positionX, position.y + c.h*scaleFactor);
rlTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);
rlVertex2f(positionX + c.w*scaleFactor, position.y + (c.h) * scaleFactor);
rlTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);
rlVertex2f(positionX + c.w*scaleFactor, position.y);
positionX += (c.w*scaleFactor + spacing);
} }
rlEnd(); else if ((unsigned char)text[i] == 0xc3)
{
letter = (unsigned char)text[i + 1];
c = spriteFont.charSet[letter - FONT_FIRST_CHAR + 64];
i++;
}
else c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR];
rlDisableTexture(); DrawTexturePro(spriteFont.texture, (Rectangle){ c.x, c.y, c.w, c.h }, (Rectangle){ position.x + offsetX, position.y, c.w*scaleFactor, c.h*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint);
offsetX += (c.w*scaleFactor + spacing);
}
} }
// Formatting of text with variables to 'embed' // Formatting of text with variables to 'embed'

View file

@ -51,10 +51,8 @@ typedef struct {
unsigned char *data; // Image raw data unsigned char *data; // Image raw data
int width; // Image base width int width; // Image base width
int height; // Image base height int height; // Image base height
//int bpp; // bytes per pixel
//int components; // num color components
int mipmaps; // Mipmap levels, 1 by default int mipmaps; // Mipmap levels, 1 by default
int compFormat; // Compressed data format, 0 if no compression int format; // Data format
} ImageEx; } ImageEx;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -134,7 +132,7 @@ Image LoadImage(const char *fileName)
ImageEx imageDDS = LoadDDS(fileName); ImageEx imageDDS = LoadDDS(fileName);
if (imageDDS.compFormat == 0) if (imageDDS.format == 0)
{ {
image.pixels = (Color *)malloc(imageDDS.width * imageDDS.height * sizeof(Color)); image.pixels = (Color *)malloc(imageDDS.width * imageDDS.height * sizeof(Color));
image.width = imageDDS.width; image.width = imageDDS.width;
@ -304,14 +302,7 @@ Texture2D LoadTexture(const char *fileName)
{ {
ImageEx image = LoadDDS(fileName); ImageEx image = LoadDDS(fileName);
if (image.compFormat == 0) texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps, false);
{
texture.id = rlglLoadTexture(image.data, image.width, image.height, R8G8B8A8, false);
}
else
{
texture.id = rlglLoadCompressedTexture(image.data, image.width, image.height, image.mipmaps, image.compFormat);
}
texture.width = image.width; texture.width = image.width;
texture.height = image.height; texture.height = image.height;
@ -325,7 +316,7 @@ Texture2D LoadTexture(const char *fileName)
{ {
ImageEx image = LoadPKM(fileName); ImageEx image = LoadPKM(fileName);
texture.id = rlglLoadCompressedTexture(image.data, image.width, image.height, image.mipmaps, image.compFormat); texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps, false);
texture.width = image.width; texture.width = image.width;
texture.height = image.height; texture.height = image.height;
@ -352,7 +343,17 @@ Texture2D LoadTexture(const char *fileName)
return texture; return texture;
} }
// TODO: Texture2D LoadTextureEx(const char *imageData, int width, int height, int colorMode) Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps)
{
Texture2D texture;
texture.width = width;
texture.height = height;
texture.id = rlglLoadTexture(data, width, height, textureFormat, mipmapCount, genMipmaps);
return texture;
}
// Load a texture from image data // Load a texture from image data
// NOTE: image is not unloaded, it must be done manually // NOTE: image is not unloaded, it must be done manually
@ -382,7 +383,7 @@ Texture2D LoadTextureFromImage(Image image, bool genMipmaps)
} }
// NOTE: rlglLoadTexture() can generate mipmaps (POT image required) // NOTE: rlglLoadTexture() can generate mipmaps (POT image required)
texture.id = rlglLoadTexture(imgData, image.width, image.height, R8G8B8A8, genMipmaps); texture.id = rlglLoadTexture(imgData, image.width, image.height, UNCOMPRESSED_R8G8B8A8, 1, genMipmaps);
texture.width = image.width; texture.width = image.width;
texture.height = image.height; texture.height = image.height;
@ -494,7 +495,7 @@ void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Co
Rectangle destRec = { (int)position.x, (int)position.y, sourceRec.width, sourceRec.height }; Rectangle destRec = { (int)position.x, (int)position.y, sourceRec.width, sourceRec.height };
Vector2 origin = { 0, 0 }; Vector2 origin = { 0, 0 };
DrawTexturePro(texture, sourceRec, destRec, origin, 0, tint); DrawTexturePro(texture, sourceRec, destRec, origin, 0.0f, tint);
} }
// Draw a part of a texture (defined by a rectangle) with 'pro' parameters // Draw a part of a texture (defined by a rectangle) with 'pro' parameters
@ -545,18 +546,6 @@ static ImageEx LoadDDS(const char *fileName)
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII #define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII #define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif
// DDS Pixel Format // DDS Pixel Format
typedef struct { typedef struct {
unsigned int size; unsigned int size;
@ -594,7 +583,7 @@ static ImageEx LoadDDS(const char *fileName)
image.width = 0; image.width = 0;
image.height = 0; image.height = 0;
image.mipmaps = 0; image.mipmaps = 0;
image.compFormat = 0; image.format = 0;
FILE *ddsFile = fopen(fileName, "rb"); FILE *ddsFile = fopen(fileName, "rb");
@ -626,8 +615,6 @@ static ImageEx LoadDDS(const char *fileName)
image.width = header.width; image.width = header.width;
image.height = header.height; image.height = header.height;
image.mipmaps = 1;
image.compFormat = 0;
if (header.ddspf.flags == 0x40 && header.ddspf.rgbBitCount == 24) // DDS_RGB, no compressed if (header.ddspf.flags == 0x40 && header.ddspf.rgbBitCount == 24) // DDS_RGB, no compressed
{ {
@ -651,6 +638,9 @@ static ImageEx LoadDDS(const char *fileName)
} }
free(buffer); free(buffer);
image.mipmaps = 1;
image.format = UNCOMPRESSED_R8G8B8;
} }
else if (header.ddspf.flags == 0x41 && header.ddspf.rgbBitCount == 32) // DDS_RGBA, no compressed else if (header.ddspf.flags == 0x41 && header.ddspf.rgbBitCount == 32) // DDS_RGBA, no compressed
{ {
@ -659,12 +649,12 @@ static ImageEx LoadDDS(const char *fileName)
fread(image.data, image.width*image.height*4, 1, ddsFile); fread(image.data, image.width*image.height*4, 1, ddsFile);
image.mipmaps = 1; image.mipmaps = 1;
image.compFormat = 0; image.format = UNCOMPRESSED_R8G8B8A8;
} }
else if ((header.ddspf.flags == 0x04) && (header.ddspf.fourCC > 0)) else if (((header.ddspf.flags == 0x04) || (header.ddspf.flags == 0x05)) && (header.ddspf.fourCC > 0))
{ {
TraceLog(WARNING, "[%s] DDS image uses compression, not supported on OpenGL 1.1", fileName); //TraceLog(WARNING, "[%s] DDS image uses compression, not supported on OpenGL 1.1", fileName);
TraceLog(WARNING, "[%s] DDS compressed files require OpenGL 3.2+ or ES 2.0", fileName); //TraceLog(WARNING, "[%s] DDS compressed files require OpenGL 3.2+ or ES 2.0", fileName);
int bufsize; int bufsize;
@ -672,6 +662,8 @@ static ImageEx LoadDDS(const char *fileName)
if (header.mipMapCount > 1) bufsize = header.pitchOrLinearSize * 2; if (header.mipMapCount > 1) bufsize = header.pitchOrLinearSize * 2;
else bufsize = header.pitchOrLinearSize; else bufsize = header.pitchOrLinearSize;
TraceLog(DEBUG, "Pitch or linear size: %i", header.pitchOrLinearSize);
image.data = (unsigned char*)malloc(bufsize * sizeof(unsigned char)); image.data = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
fread(image.data, 1, bufsize, ddsFile); fread(image.data, 1, bufsize, ddsFile);
@ -680,19 +672,18 @@ static ImageEx LoadDDS(const char *fileName)
fclose(ddsFile); fclose(ddsFile);
image.mipmaps = header.mipMapCount; image.mipmaps = header.mipMapCount;
image.compFormat = 0;
switch(header.ddspf.fourCC) switch(header.ddspf.fourCC)
{ {
case FOURCC_DXT1: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; case FOURCC_DXT1:
case FOURCC_DXT3: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; {
case FOURCC_DXT5: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; if (header.ddspf.flags == 0x04) image.format = COMPRESSED_DXT1_RGB;
else image.format = COMPRESSED_DXT1_RGBA;
} break;
case FOURCC_DXT3: image.format = COMPRESSED_DXT3_RGBA; break;
case FOURCC_DXT5: image.format = COMPRESSED_DXT5_RGBA; break;
default: break; default: break;
} }
// NOTE: Image num color components not required... for now...
//if (fourCC == FOURCC_DXT1) image.components = 3;
//else image.components = 4;
} }
} }
} }
@ -708,10 +699,6 @@ static ImageEx LoadPKM(const char *fileName)
// If OpenGL ES 2.0. the following format could be supported (ETC1): // If OpenGL ES 2.0. the following format could be supported (ETC1):
//GL_ETC1_RGB8_OES //GL_ETC1_RGB8_OES
#ifndef GL_ETC1_RGB8_OES
#define GL_ETC1_RGB8_OES 0x8D64
#endif
// If OpenGL ES 3.0, the following formats are supported (ETC2/EAC): // If OpenGL ES 3.0, the following formats are supported (ETC2/EAC):
//GL_COMPRESSED_RGB8_ETC2 //GL_COMPRESSED_RGB8_ETC2
//GL_COMPRESSED_RGBA8_ETC2 //GL_COMPRESSED_RGBA8_ETC2
@ -780,7 +767,7 @@ static ImageEx LoadPKM(const char *fileName)
image.width = width; image.width = width;
image.height = height; image.height = height;
image.mipmaps = 1; image.mipmaps = 1;
image.compFormat = GL_ETC1_RGB8_OES; image.format = COMPRESSED_ETC1_RGB;
} }
} }