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:
parent
2b4a1f295a
commit
a632a04a30
153
src/core.c
153
src/core.c
@ -267,7 +267,6 @@ static bool cameraUseGravity = true;
|
||||
|
||||
// Shaders variables
|
||||
static bool enabledPostpro = false;
|
||||
static unsigned int fboShader = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Other Modules Functions Declaration (required by core)
|
||||
@ -327,7 +326,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition);
|
||||
// Initialize Window and Graphics Context (OpenGL)
|
||||
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...)
|
||||
windowTitle = title;
|
||||
@ -366,7 +365,7 @@ void InitWindow(int width, int height, const char *title)
|
||||
// Android activity initialization
|
||||
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();
|
||||
|
||||
@ -554,9 +553,8 @@ void BeginDrawing(void)
|
||||
void EndDrawing(void)
|
||||
{
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
// TODO: Set postprocessing shader to be passed: SetPostproShader()?
|
||||
if (enabledPostpro) rlglDrawPostpro(fboShader); // Draw postprocessing effect (shader)
|
||||
|
||||
if (enabledPostpro) rlglDrawPostpro(); // Draw postprocessing effect (shader)
|
||||
|
||||
SwapBuffers(); // Copy back buffer to front buffer
|
||||
PollInputEvents(); // Poll user events
|
||||
@ -604,7 +602,7 @@ void Begin3dMode(Camera camera)
|
||||
// Setup Camera view
|
||||
if (cameraMode == CAMERA_CUSTOM) currentCamera = camera;
|
||||
else currentCamera = internalCamera;
|
||||
|
||||
|
||||
Matrix view = MatrixLookAt(currentCamera.position, currentCamera.target, currentCamera.up);
|
||||
rlMultMatrixf(GetMatrixVector(view)); // Multiply MODELVIEW matrix by view matrix (camera)
|
||||
}
|
||||
@ -707,54 +705,54 @@ void ShowLogo(void)
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera)
|
||||
{
|
||||
Ray ray;
|
||||
|
||||
|
||||
Matrix proj = MatrixIdentity();
|
||||
Matrix view = MatrixLookAt(currentCamera.position, currentCamera.target, currentCamera.up);
|
||||
|
||||
|
||||
float aspect = (GLfloat)GetScreenWidth()/(GLfloat)GetScreenHeight();
|
||||
double top = 0.1f*tanf(45.0f*PI / 360.0f);
|
||||
double right = top*aspect;
|
||||
|
||||
|
||||
proj = MatrixFrustum(-right, right, -top, top, 0.01f, 1000.0f);
|
||||
MatrixTranspose(&proj);
|
||||
|
||||
float realy = (float)GetScreenHeight() - mousePosition.y;
|
||||
|
||||
|
||||
float z;
|
||||
// glReadPixels(mousePosition.x, mousePosition.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
|
||||
//http://www.bfilipek.com/2012/06/select-mouse-opengl.html
|
||||
|
||||
Vector3 nearPoint = { mousePosition.x, realy, 0.0f };
|
||||
Vector3 farPoint = { mousePosition.x, realy, 1.0f };
|
||||
|
||||
|
||||
nearPoint = internalCamera.position;
|
||||
farPoint = rlglUnproject(farPoint, proj, view);
|
||||
|
||||
|
||||
Vector3 direction = VectorSubtract(farPoint, nearPoint);
|
||||
VectorNormalize(&direction);
|
||||
|
||||
ray.position = nearPoint;
|
||||
|
||||
ray.position = nearPoint;
|
||||
ray.direction = direction;
|
||||
|
||||
|
||||
// Test
|
||||
Vector2 screenPos;
|
||||
screenPos.x = (mousePosition.x / (float)GetScreenWidth() * 2.0) - 1.0f;
|
||||
screenPos.y = (mousePosition.y / (float)GetScreenHeight() * 2.0) - 1.0f;
|
||||
|
||||
|
||||
direction = VectorSubtract(internalCamera.target, internalCamera.position);
|
||||
|
||||
|
||||
printf("/nScreenPos %f, %f", screenPos.x, screenPos.y);
|
||||
|
||||
|
||||
Matrix rotate;
|
||||
rotate = MatrixIdentity();
|
||||
rotate = MatrixRotate(0, 45*DEG2RAD*screenPos.y, 0);
|
||||
VectorTransform(&direction, rotate);
|
||||
|
||||
|
||||
VectorNormalize(&direction);
|
||||
|
||||
ray.position = internalCamera.position;
|
||||
|
||||
ray.position = internalCamera.position;
|
||||
ray.direction = direction;
|
||||
|
||||
|
||||
return ray;
|
||||
}
|
||||
|
||||
@ -790,7 +788,7 @@ void SetCameraMode(int mode)
|
||||
internalCamera.target = (Vector3){ 3, 0, 3};
|
||||
ProcessCamera(&internalCamera, &internalCamera.position);
|
||||
}
|
||||
|
||||
|
||||
cameraMode = mode;
|
||||
}
|
||||
|
||||
@ -798,7 +796,7 @@ Camera UpdateCamera(Vector3 *position)
|
||||
{
|
||||
// Calculate camera
|
||||
if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position);
|
||||
|
||||
|
||||
return internalCamera;
|
||||
}
|
||||
|
||||
@ -1114,16 +1112,23 @@ Vector2 GetTouchPosition(void)
|
||||
}*/
|
||||
#endif
|
||||
|
||||
void InitPostShader(void)
|
||||
// Set postprocessing shader
|
||||
void SetPostproShader(Shader shader)
|
||||
{
|
||||
rlglInitPostpro();
|
||||
|
||||
enabledPostpro = true;
|
||||
}
|
||||
|
||||
void SetPostShader(unsigned int shader)
|
||||
{
|
||||
fboShader = shader;
|
||||
if (rlGetVersion() == OPENGL_11) TraceLog(WARNING, "Postprocessing shaders not supported on OpenGL 1.1");
|
||||
else
|
||||
{
|
||||
if (!enabledPostpro)
|
||||
{
|
||||
enabledPostpro = true;
|
||||
rlglInitPostpro();
|
||||
rlglSetPostproShader(shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
rlglSetPostproShader(shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -1894,7 +1899,7 @@ static void PollInputEvents(void)
|
||||
|
||||
previousMouseWheelY = currentMouseWheelY;
|
||||
currentMouseWheelY = 0;
|
||||
|
||||
|
||||
glfwPollEvents(); // Register keyboard/mouse events... and window events!
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
|
||||
@ -2412,7 +2417,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
cameraMouseVariation.x = GetMousePosition().x - cameraMousePosition.x;
|
||||
cameraMouseVariation.y = GetMousePosition().y - cameraMousePosition.y;
|
||||
}
|
||||
|
||||
|
||||
cameraMousePosition = GetMousePosition();
|
||||
|
||||
// Support for multiple automatic camera modes
|
||||
@ -2422,12 +2427,12 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
{
|
||||
// Pass to orbiting camera
|
||||
if (IsKeyPressed('O')) cameraMode = CAMERA_ORBITAL;
|
||||
|
||||
|
||||
// Camera zoom
|
||||
if ((cameraTargetDistance < FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0))
|
||||
{
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
|
||||
|
||||
if (cameraTargetDistance > FREE_CAMERA_DISTANCE_MAX_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MAX_CLAMP;
|
||||
}
|
||||
// Camera looking down
|
||||
@ -2442,7 +2447,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
|
||||
|
||||
if (camera->target.y < 0) camera->target.y = -0.001;
|
||||
}
|
||||
else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (GetMouseWheelMove() > 0))
|
||||
@ -2462,7 +2467,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
|
||||
|
||||
if (camera->target.y > 0) camera->target.y = 0.001;
|
||||
}
|
||||
else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (GetMouseWheelMove() > 0))
|
||||
@ -2470,8 +2475,8 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Inputs
|
||||
if (IsKeyDown(KEY_LEFT_ALT))
|
||||
{
|
||||
@ -2487,7 +2492,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -FREE_CAMERA_MOUSE_SENSITIVITY;
|
||||
cameraAngle.y += cameraMouseVariation.y * -FREE_CAMERA_MOUSE_SENSITIVITY;
|
||||
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > FREE_CAMERA_MIN_CLAMP * DEG2RAD) cameraAngle.y = FREE_CAMERA_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < FREE_CAMERA_MAX_CLAMP * DEG2RAD) cameraAngle.y = FREE_CAMERA_MAX_CLAMP * DEG2RAD;
|
||||
@ -2500,55 +2505,55 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
camera->target.y += ((cameraMouseVariation.y * FREE_CAMERA_MOUSE_SENSITIVITY) * cos(cameraAngle.y)) * (cameraTargetDistance / FREE_CAMERA_PANNING_DIVIDER);
|
||||
camera->target.z += ((cameraMouseVariation.x * FREE_CAMERA_MOUSE_SENSITIVITY) * sin(cameraAngle.x) + (cameraMouseVariation.y * FREE_CAMERA_MOUSE_SENSITIVITY) * cos(cameraAngle.x) * sin(cameraAngle.y)) * (cameraTargetDistance / FREE_CAMERA_PANNING_DIVIDER);
|
||||
}
|
||||
|
||||
|
||||
// Focus to center
|
||||
if (IsKeyDown('Z')) camera->target = (Vector3) { 0, 0, 0 };
|
||||
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
camera->position.z = cos(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.z;
|
||||
|
||||
|
||||
} break;
|
||||
case CAMERA_ORBITAL:
|
||||
{
|
||||
// Pass to free camera
|
||||
if (IsKeyPressed('O')) cameraMode = CAMERA_FREE;
|
||||
|
||||
|
||||
cameraAngle.x += ORBITAL_CAMERA_SPEED;
|
||||
|
||||
|
||||
// Camera zoom
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP;
|
||||
|
||||
|
||||
// Focus to center
|
||||
if (IsKeyDown('Z')) camera->target = (Vector3) { 0, 0, 0 };
|
||||
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
camera->position.z = cos(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.z;
|
||||
|
||||
|
||||
} break;
|
||||
case CAMERA_FIRST_PERSON:
|
||||
case CAMERA_THIRD_PERSON:
|
||||
{
|
||||
bool isMoving = false;
|
||||
|
||||
|
||||
// Keyboard inputs
|
||||
if (IsKeyDown('W'))
|
||||
{
|
||||
playerPosition->x -= sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z -= cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
if (!cameraUseGravity) camera->position.y += sin(cameraAngle.y) / PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
|
||||
isMoving = true;
|
||||
}
|
||||
else if (IsKeyDown('S'))
|
||||
@ -2556,25 +2561,25 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
playerPosition->x += sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z += cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
if (!cameraUseGravity) camera->position.y -= sin(cameraAngle.y) / PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
|
||||
isMoving = true;
|
||||
}
|
||||
|
||||
|
||||
if (IsKeyDown('A'))
|
||||
{
|
||||
playerPosition->x -= cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z += sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
|
||||
isMoving = true;
|
||||
}
|
||||
else if (IsKeyDown('D'))
|
||||
{
|
||||
playerPosition->x += cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z -= sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
|
||||
isMoving = true;
|
||||
}
|
||||
|
||||
|
||||
if (IsKeyDown('E'))
|
||||
{
|
||||
if (!cameraUseGravity) playerPosition->y += 1 / PLAYER_MOVEMENT_DIVIDER;
|
||||
@ -2583,32 +2588,32 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
{
|
||||
if (!cameraUseGravity) playerPosition->y -= 1 / PLAYER_MOVEMENT_DIVIDER;
|
||||
}
|
||||
|
||||
|
||||
if (cameraMode == CAMERA_THIRD_PERSON)
|
||||
{
|
||||
// Camera orientation calculation
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -THIRD_PERSON_MOUSE_SENSITIVITY;
|
||||
cameraAngle.y += cameraMouseVariation.y * -THIRD_PERSON_MOUSE_SENSITIVITY;
|
||||
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > THIRD_PERSON_MIN_CLAMP * DEG2RAD) cameraAngle.y = THIRD_PERSON_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < THIRD_PERSON_MAX_CLAMP * DEG2RAD) cameraAngle.y = THIRD_PERSON_MAX_CLAMP * DEG2RAD;
|
||||
|
||||
|
||||
// Camera zoom
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP;
|
||||
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = playerPosition->x + THIRD_PERSON_OFFSET.x * cos(cameraAngle.x) + THIRD_PERSON_OFFSET.z * sin(cameraAngle.x);
|
||||
camera->target.y = playerPosition->y + PLAYER_HEIGHT * FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + THIRD_PERSON_OFFSET.y;
|
||||
camera->target.z = playerPosition->z + THIRD_PERSON_OFFSET.z * sin(cameraAngle.x) - THIRD_PERSON_OFFSET.x * sin(cameraAngle.x);
|
||||
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
@ -2617,25 +2622,25 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
else
|
||||
{
|
||||
if (isMoving) cameraMovementCounter++;
|
||||
|
||||
|
||||
// Camera orientation calculation
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -FIRST_PERSON_MOUSE_SENSITIVITY;
|
||||
cameraAngle.y += cameraMouseVariation.y * -FIRST_PERSON_MOUSE_SENSITIVITY;
|
||||
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > FIRST_PERSON_MIN_CLAMP * DEG2RAD) cameraAngle.y = FIRST_PERSON_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < FIRST_PERSON_MAX_CLAMP * DEG2RAD) cameraAngle.y = FIRST_PERSON_MAX_CLAMP * DEG2RAD;
|
||||
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = camera->position.x - sin(cameraAngle.x) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.y = camera->position.y + sin(cameraAngle.y) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.z = camera->position.z - cos(cameraAngle.x) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
|
||||
|
||||
camera->position.x = playerPosition->x;
|
||||
camera->position.y = (playerPosition->y + PLAYER_HEIGHT * FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMovementCounter / FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER) / FIRST_PERSON_STEP_DIVIDER;
|
||||
camera->position.z = playerPosition->z;
|
||||
|
||||
|
||||
camera->up.x = sin(cameraMovementCounter / (FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER * 2)) / FIRST_PERSON_WAVING_DIVIDER;
|
||||
camera->up.z = -sin(cameraMovementCounter / (FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER * 2)) / FIRST_PERSON_WAVING_DIVIDER;
|
||||
}
|
||||
|
281
src/models.c
281
src/models.c
@ -324,7 +324,7 @@ void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Col
|
||||
rlPushMatrix();
|
||||
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
||||
rlScalef(radius, radius, radius);
|
||||
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
@ -444,48 +444,17 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
|
||||
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
|
||||
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+
|
||||
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();
|
||||
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
||||
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);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlNormal3f(0.0f, 1.0f, 0.0f);
|
||||
@ -499,57 +468,27 @@ void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
|
||||
if (rlGetVersion() != OPENGL_11) rlDisableTexture();
|
||||
}
|
||||
|
||||
// Draw a plane with divisions
|
||||
// TODO: Test this function
|
||||
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color)
|
||||
// Draw a quad
|
||||
void DrawQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Color color)
|
||||
{
|
||||
float quadWidth = size.x / slicesX;
|
||||
float quadLenght = size.y / slicesZ;
|
||||
// TODO: Calculate normals from vertex position
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
//rlNormal3f(0.0f, 0.0f, 0.0f);
|
||||
|
||||
float texPieceW = 1 / size.x;
|
||||
float texPieceH = 1 / size.y;
|
||||
|
||||
// NOTE: Plane is always created on XZ ground and then rotated
|
||||
rlPushMatrix();
|
||||
rlTranslatef(-size.x / 2, 0.0f, -size.y / 2);
|
||||
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
||||
|
||||
// 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();
|
||||
rlVertex3f(v1.x, v1.y, v1.z);
|
||||
rlVertex3f(v2.x, v2.y, v2.z);
|
||||
rlVertex3f(v3.x, v3.y, v3.z);
|
||||
rlVertex3f(v4.x, v4.y, v4.z);
|
||||
rlEnd();
|
||||
}
|
||||
|
||||
// Draw a ray line
|
||||
void DrawRay(Ray ray, Color color)
|
||||
{
|
||||
float scale = 10000;
|
||||
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
@ -615,76 +554,7 @@ void DrawGizmo(Vector3 position)
|
||||
rlPopMatrix();
|
||||
}
|
||||
|
||||
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale)
|
||||
{
|
||||
// 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
|
||||
// Load a 3d model (from file)
|
||||
Model LoadModel(const char *fileName)
|
||||
{
|
||||
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: model properties (transform, texture, shader) are initialized inside rlglLoadModel()
|
||||
Model model = rlglLoadModel(vData); // Upload vertex data to GPU
|
||||
|
||||
// Now that vertex data is uploaded to GPU, we can free arrays
|
||||
@ -708,6 +579,19 @@ Model LoadModel(const char *fileName)
|
||||
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
|
||||
Model LoadHeightmap(Image heightmap, float maxHeight)
|
||||
{
|
||||
@ -847,12 +731,12 @@ Model LoadCubicmap(Image cubesmap)
|
||||
|
||||
float w = 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));
|
||||
Vector2 *mapTexcoords = (Vector2 *)malloc(maxTriangles * 3 * sizeof(Vector2));
|
||||
Vector3 *mapNormals = (Vector3 *)malloc(maxTriangles * 3 * sizeof(Vector3));
|
||||
|
||||
|
||||
// Define the 6 normals of the cube, we will combine them accordingly later...
|
||||
Vector3 n1 = { 1.0f, 0.0f, 0.0f };
|
||||
Vector3 n2 = { -1.0f, 0.0f, 0.0f };
|
||||
@ -868,14 +752,14 @@ Model LoadCubicmap(Image cubesmap)
|
||||
float width;
|
||||
float height;
|
||||
} RectangleF;
|
||||
|
||||
|
||||
RectangleF rightTexUV = { 0, 0, 0.5, 0.5 };
|
||||
RectangleF leftTexUV = { 0.5, 0, 0.5, 0.5 };
|
||||
RectangleF frontTexUV = { 0, 0, 0.5, 0.5 };
|
||||
RectangleF backTexUV = { 0.5, 0, 0.5, 0.5 };
|
||||
RectangleF topTexUV = { 0, 0.5, 0.5, 0.5 };
|
||||
RectangleF bottomTexUV = { 0.5, 0.5, 0.5, 0.5 };
|
||||
|
||||
|
||||
for (int z = 0; z < mapHeight; z += mapCubeSide)
|
||||
{
|
||||
for (int x = 0; x < mapWidth; x += mapCubeSide)
|
||||
@ -1105,7 +989,7 @@ Model LoadCubicmap(Image cubesmap)
|
||||
mapTexcoords[tcCounter + 4] = (Vector2){ topTexUV.x + topTexUV.width, topTexUV.y };
|
||||
mapTexcoords[tcCounter + 5] = (Vector2){ topTexUV.x + topTexUV.width, topTexUV.y + topTexUV.height };
|
||||
tcCounter += 6;
|
||||
|
||||
|
||||
// Define bottom triangles (2 tris, 6 vertex --> v6-v8-v7, v6-v5-v8)
|
||||
mapVertices[vCounter] = v6;
|
||||
mapVertices[vCounter + 1] = v7;
|
||||
@ -1208,11 +1092,11 @@ void UnloadModel(Model model)
|
||||
free(model.mesh.normals);
|
||||
}
|
||||
|
||||
rlDeleteBuffers(model.vboId[0]);
|
||||
rlDeleteBuffers(model.vboId[1]);
|
||||
rlDeleteBuffers(model.vboId[2]);
|
||||
rlDeleteBuffers(model.mesh.vboId[0]);
|
||||
rlDeleteBuffers(model.mesh.vboId[1]);
|
||||
rlDeleteBuffers(model.mesh.vboId[2]);
|
||||
|
||||
rlDeleteVertexArrays(model.vaoId);
|
||||
rlDeleteVertexArrays(model.mesh.vaoId);
|
||||
rlDeleteTextures(model.texture.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)
|
||||
{
|
||||
Vector3 vScale = { scale, scale, scale };
|
||||
float rotAngle = 0.0f;
|
||||
Vector3 rotAxis = { 0, 0, 0 };
|
||||
Vector3 rotationAxis = { 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
|
||||
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()
|
||||
|
||||
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)
|
||||
{
|
||||
Vector3 vScale = { scale, scale, scale };
|
||||
float rotAngle = 0.0f;
|
||||
Vector3 rotAxis = { 0, 0, 0 };
|
||||
Vector3 rotationAxis = { 0, 0, 0 };
|
||||
|
||||
rlglDrawModel(model, position, rotAngle, rotAxis, vScale, color, true);
|
||||
rlglDrawModel(model, position, 0.0f, rotationAxis, vScale, color, true);
|
||||
}
|
||||
|
||||
// Draw a billboard
|
||||
@ -1360,7 +1241,7 @@ bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, floa
|
||||
float distance = sqrt(dx*dx + dy*dy + dz*dz); // Distance between centers
|
||||
|
||||
if (distance <= (radiusA + radiusB)) collision = true;
|
||||
|
||||
|
||||
return collision;
|
||||
}
|
||||
|
||||
@ -1379,9 +1260,9 @@ bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, V
|
||||
|
||||
bounds = new BoundingBox(minVertex, maxVertex);
|
||||
*/
|
||||
|
||||
|
||||
bool collision = true;
|
||||
|
||||
|
||||
if ((maxBBox1.x >= minBBox2.x) && (minBBox1.x <= maxBBox2.x))
|
||||
{
|
||||
if ((maxBBox1.y < minBBox2.y) || (minBBox1.y > maxBBox2.y)) collision = false;
|
||||
@ -1395,7 +1276,7 @@ bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, V
|
||||
bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere)
|
||||
{
|
||||
bool collision = false;
|
||||
|
||||
|
||||
if ((centerSphere.x - minBBox.x > radiusSphere) && (centerSphere.y - minBBox.y > radiusSphere) && (centerSphere.z - minBBox.z > radiusSphere) &&
|
||||
(maxBBox.x - centerSphere.x > radiusSphere) && (maxBBox.y - centerSphere.y > radiusSphere) && (maxBBox.z - centerSphere.z > radiusSphere))
|
||||
{
|
||||
@ -1435,20 +1316,20 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
|
||||
{
|
||||
// Detect the cell where the player is located
|
||||
Vector3 impactDirection = { 0, 0, 0 };
|
||||
|
||||
|
||||
int locationCellX = 0;
|
||||
int locationCellY = 0;
|
||||
|
||||
|
||||
locationCellX = floor(playerPosition->x + mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE);
|
||||
locationCellY = floor(playerPosition->z + mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE);
|
||||
|
||||
|
||||
// Multiple Axis --------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Axis x-, y-
|
||||
if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0) &&
|
||||
(cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
|
||||
{
|
||||
playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
@ -1456,12 +1337,12 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
|
||||
impactDirection = (Vector3) { 1, 0, 1};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Axis x-, y+
|
||||
if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0) &&
|
||||
(cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
|
||||
{
|
||||
playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
@ -1469,12 +1350,12 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
|
||||
impactDirection = (Vector3) { 1, 0, 1};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Axis x+, y-
|
||||
if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX + 1)].r != 0) &&
|
||||
(cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
|
||||
{
|
||||
playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
@ -1482,12 +1363,12 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
|
||||
impactDirection = (Vector3) { 1, 0, 1};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Axis x+, y+
|
||||
if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX + 1)].r != 0) &&
|
||||
(cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
|
||||
{
|
||||
playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
@ -1495,9 +1376,9 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
|
||||
impactDirection = (Vector3) { 1, 0, 1};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Single Axis ---------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Axis x-
|
||||
if (cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0)
|
||||
{
|
||||
@ -1534,89 +1415,89 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
|
||||
impactDirection = (Vector3) { 0, 0, 1};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Diagonals -------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Axis x-, y-
|
||||
if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX - 1)].r == 0) &&
|
||||
(cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r == 0) &&
|
||||
(cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX - 1)].r != 0))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) > ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY)) playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
else playerPosition->z = locationCellY - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
|
||||
|
||||
// Return ricochet
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius / 3))
|
||||
{
|
||||
impactDirection = (Vector3) { 1, 0, 1};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Axis x-, y+
|
||||
if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX - 1)].r == 0) &&
|
||||
(cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r == 0) &&
|
||||
(cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX - 1)].r != 0))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) > (1 - ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY))) playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
else playerPosition->z = locationCellY + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
|
||||
|
||||
// Return ricochet
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius / 3))
|
||||
{
|
||||
impactDirection = (Vector3) { 1, 0, 1};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Axis x+, y-
|
||||
if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX + 1)].r == 0) &&
|
||||
(cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r == 0) &&
|
||||
(cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX + 1)].r != 0))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) < (1 - ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY))) playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
else playerPosition->z = locationCellY - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
|
||||
|
||||
// Return ricochet
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius / 3))
|
||||
{
|
||||
impactDirection = (Vector3) { 1, 0, 1};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Axis x+, y+
|
||||
if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX + 1)].r == 0) &&
|
||||
(cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r == 0) &&
|
||||
(cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX + 1)].r != 0))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
|
||||
{
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) < ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY)) playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
else playerPosition->z = locationCellY + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
|
||||
|
||||
|
||||
// Return ricochet
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) &&
|
||||
if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) &&
|
||||
((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius / 3))
|
||||
{
|
||||
impactDirection = (Vector3) { 1, 0, 1};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Floor collision
|
||||
if (playerPosition->y <= radius)
|
||||
{
|
||||
@ -1629,7 +1510,7 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p
|
||||
playerPosition->y = (1.5 - radius) - 0.01;
|
||||
impactDirection = (Vector3) { impactDirection.x, 1, impactDirection.z};
|
||||
}
|
||||
|
||||
|
||||
return impactDirection;
|
||||
}
|
||||
|
||||
|
55
src/raylib.h
55
src/raylib.h
@ -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
|
||||
*
|
||||
@ -199,6 +199,14 @@ typedef struct Vector3 {
|
||||
float z;
|
||||
} 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)
|
||||
typedef struct Color {
|
||||
unsigned char r;
|
||||
@ -258,24 +266,27 @@ typedef struct Camera {
|
||||
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
|
||||
|
||||
// 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 {
|
||||
int vertexCount;
|
||||
float *vertices; // 3 components per vertex
|
||||
float *texcoords; // 2 components per vertex
|
||||
float *normals; // 3 components per vertex
|
||||
unsigned char *colors; // 4 components per vertex
|
||||
unsigned int vaoId;
|
||||
unsigned int vboId[4];
|
||||
} VertexData;
|
||||
|
||||
// Shader type
|
||||
typedef struct Shader {
|
||||
unsigned int id; // Shader program id
|
||||
|
||||
|
||||
// Variable attributes
|
||||
unsigned int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
unsigned int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
unsigned int normalLoc; // Normal attribute location point (vertex shader)
|
||||
unsigned int colorLoc; // Color attibute location point (vertex shader)
|
||||
|
||||
|
||||
// Uniforms
|
||||
unsigned int projectionLoc; // Projection matrix uniform location point (vertex shader)
|
||||
unsigned int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
|
||||
@ -284,14 +295,11 @@ typedef struct Shader {
|
||||
} Shader;
|
||||
|
||||
// 3d Model type
|
||||
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
unsigned int vaoId;
|
||||
unsigned int vboId[4];
|
||||
Matrix transform;
|
||||
Texture2D texture;
|
||||
Shader shader;
|
||||
//Matrix transform;
|
||||
} Model;
|
||||
|
||||
// Ray type (useful for raycast)
|
||||
@ -315,6 +323,24 @@ typedef struct Wave {
|
||||
short channels;
|
||||
} 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
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
@ -366,8 +392,7 @@ Camera UpdateCamera(Vector3 *position); // Update camera wit
|
||||
void SetConfigFlags(char flags); // Enable some window configurations
|
||||
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
||||
|
||||
void InitPostShader(void); // Initialize fullscreen postproduction shaders system
|
||||
void SetPostShader(unsigned int shader); // Set fullscreen postproduction shader
|
||||
void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
|
||||
|
||||
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 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 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 LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps)
|
||||
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 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 DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4]); // Draw a quad
|
||||
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
|
||||
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);
|
||||
void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
|
||||
void DrawQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Color color); // Draw a quad
|
||||
void DrawRay(Ray ray, Color color); // Draw a ray line
|
||||
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
|
||||
void DrawGizmo(Vector3 position); // Draw simple gizmo
|
||||
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale); // Draw gizmo with extended parameters
|
||||
//DrawTorus(), DrawTeapot() are useless...
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Model 3d Loading and Drawing Functions (Module: models)
|
||||
//------------------------------------------------------------------------------------
|
||||
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 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)
|
||||
@ -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 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 CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2);
|
||||
|
@ -53,15 +53,15 @@
|
||||
float y;
|
||||
float z;
|
||||
} Vector3;
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
// Quaternion type
|
||||
typedef struct Quaternion {
|
||||
|
516
src/rlgl.c
516
src/rlgl.c
@ -63,6 +63,28 @@
|
||||
#define TEMP_VERTEX_BUFFER_SIZE 4096 // Temporal Vertex Buffer (required for vertex-transformations)
|
||||
// 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
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -174,7 +196,8 @@ static bool useTempBuffer = false;
|
||||
static bool vaoSupported = false;
|
||||
|
||||
// Framebuffer object and texture
|
||||
static GLuint fbo, fboColorTexture, fboDepthTexture, fboShader = 0;
|
||||
static GLuint fbo, fboColorTexture, fboDepthTexture;
|
||||
static Model postproQuad;
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
@ -199,6 +222,7 @@ static Shader LoadSimpleShader(void);
|
||||
static void InitializeBuffers(void);
|
||||
static void InitializeBuffersGPU(void);
|
||||
static void UpdateBuffers(void);
|
||||
static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat);
|
||||
|
||||
// Custom shader files loading (external)
|
||||
static char *TextFileRead(char *fn);
|
||||
@ -688,18 +712,21 @@ void rlDeleteTextures(unsigned int id)
|
||||
glDeleteTextures(1, &id);
|
||||
}
|
||||
|
||||
// Enable rendering to postprocessing FBO
|
||||
void rlEnableFBO(void)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Unload shader from GPU memory
|
||||
void rlDeleteShader(unsigned int id)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glDeleteProgram(id);
|
||||
}
|
||||
|
||||
void rlEnableFBO(void)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Unload vertex data (VAO) from GPU memory
|
||||
void rlDeleteVertexArrays(unsigned int id)
|
||||
@ -840,7 +867,18 @@ void rlglInit(void)
|
||||
TraceLog(INFO, "Supported extension: %s", extensions);
|
||||
#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)
|
||||
// Set default draw mode
|
||||
currentDrawMode = RL_TRIANGLES;
|
||||
@ -869,7 +907,7 @@ void rlglInit(void)
|
||||
// Create default white texture for plain colors (required by shader)
|
||||
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);
|
||||
else TraceLog(WARNING, "Base white texture could not be loaded");
|
||||
@ -884,14 +922,14 @@ void rlglInit(void)
|
||||
}
|
||||
|
||||
drawsCounter = 1;
|
||||
draws[drawsCounter - 1].textureId = whiteTexture;
|
||||
draws[drawsCounter - 1].textureId = whiteTexture;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// Init postpro system
|
||||
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
|
||||
glGenTextures(1, &fboColorTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, fboColorTexture);
|
||||
@ -901,7 +939,7 @@ void rlglInitPostpro(void)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GetScreenWidth(), GetScreenHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
|
||||
// Create the texture that will serve as the depth attachment for the framebuffer.
|
||||
glGenTextures(1, &fboDepthTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, fboDepthTexture);
|
||||
@ -921,17 +959,48 @@ void rlglInitPostpro(void)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fboDepthTexture, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) TraceLog(WARNING, "Framebuffer object could not be created...");
|
||||
else TraceLog(INFO, "[FBO ID %i] Framebuffer object created successfully", fbo);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// Create a simple quad model to render fbo texture
|
||||
VertexData quadData;
|
||||
|
||||
fboShader = 0;
|
||||
quadData.vertexCount = 6;
|
||||
|
||||
// TODO: Init simple quad VAO and data here?
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
void rlglClose(void)
|
||||
@ -987,8 +1056,13 @@ void rlglClose(void)
|
||||
|
||||
// Free GPU texture
|
||||
glDeleteTextures(1, &whiteTexture);
|
||||
|
||||
if (fbo != 0) glDeleteFramebuffers(1, &fbo);
|
||||
|
||||
if (fbo != 0)
|
||||
{
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
|
||||
UnloadModel(postproQuad);
|
||||
}
|
||||
|
||||
free(draws);
|
||||
#endif
|
||||
@ -1002,7 +1076,7 @@ void rlglDraw(void)
|
||||
if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0))
|
||||
{
|
||||
glUseProgram(defaultShader.id);
|
||||
|
||||
|
||||
glUniformMatrix4fv(defaultShader.projectionLoc, 1, false, GetMatrixVector(projection));
|
||||
glUniformMatrix4fv(defaultShader.modelviewLoc, 1, false, GetMatrixVector(modelview));
|
||||
glUniform1i(defaultShader.textureLoc, 0);
|
||||
@ -1142,68 +1216,15 @@ void rlglDraw(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
void rlglDrawPostpro(unsigned int shaderId)
|
||||
// Draw with postprocessing shader
|
||||
void rlglDrawPostpro(void)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// TODO: Draw screen quad with texture
|
||||
/*
|
||||
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();
|
||||
}
|
||||
rlglDrawModel(postproQuad, (Vector3){0,0,0}, 0.0f, (Vector3){0,0,0}, (Vector3){1.0f, 1.0f, 1.0f}, WHITE, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw a 3d model
|
||||
void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires)
|
||||
@ -1250,12 +1271,14 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
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)
|
||||
Matrix transform = MatrixTransform(position, rotation, scale); // Object-space transformation
|
||||
Matrix modelviewworld = MatrixMultiply(transform, modelview); // World-space transformation
|
||||
|
||||
|
||||
// Projection: Screen-space transformation
|
||||
|
||||
// NOTE: Drawing in OpenGL 3.3+, transform is passed to shader
|
||||
@ -1271,21 +1294,21 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
|
||||
|
||||
if (vaoSupported)
|
||||
{
|
||||
glBindVertexArray(model.vaoId);
|
||||
glBindVertexArray(model.mesh.vaoId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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);
|
||||
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);
|
||||
glEnableVertexAttribArray(model.shader.texcoordLoc);
|
||||
|
||||
// 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);
|
||||
glEnableVertexAttribArray(model.shader.normalLoc);
|
||||
}
|
||||
@ -1357,10 +1380,10 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height)
|
||||
|
||||
// Get world coordinates from screen coordinates
|
||||
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
|
||||
{
|
||||
{
|
||||
//GLint viewport[4];
|
||||
//glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
|
||||
// Viewport data
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
@ -1368,7 +1391,7 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
|
||||
int height = GetScreenHeight();
|
||||
float minDepth = 0.0f;
|
||||
float maxDepth = 1.0f;
|
||||
/*
|
||||
/*
|
||||
Matrix modelviewprojection = MatrixMultiply(modelview, projection);
|
||||
MatrixInvert(&modelviewprojection);
|
||||
|
||||
@ -1384,7 +1407,7 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
|
||||
|
||||
//if (!MathUtil.IsOne(a)) vector = (vector / a);
|
||||
//VectorScale(&vector, 1/a);
|
||||
|
||||
|
||||
return vector;
|
||||
*/
|
||||
/*
|
||||
@ -1418,31 +1441,31 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
|
||||
/*
|
||||
Quaternion quat;
|
||||
Vector3 vec;
|
||||
|
||||
|
||||
quat.x = 2.0f * GetMousePosition().x / (float)width - 1;
|
||||
quat.y = -(2.0f * GetMousePosition().y / (float)height - 1);
|
||||
quat.z = 0;
|
||||
quat.w = 1;
|
||||
|
||||
Matrix invView;
|
||||
|
||||
Matrix invView;
|
||||
MatrixInvert(&view);
|
||||
Matrix invProj;
|
||||
MatrixInvert(&proj);
|
||||
|
||||
|
||||
quat.x = invProj.m0 * quat.x + invProj.m4 * quat.y + invProj.m8 * quat.z + invProj.m12 * quat.w;
|
||||
quat.y = invProj.m1 * quat.x + invProj.m5 * quat.y + invProj.m9 * quat.z + invProj.m13 * quat.w;
|
||||
quat.z = invProj.m2 * quat.x + invProj.m6 * quat.y + invProj.m10 * quat.z + invProj.m14 * quat.w;
|
||||
quat.w = invProj.m3 * quat.x + invProj.m7 * quat.y + invProj.m11 * quat.z + invProj.m15 * quat.w;
|
||||
|
||||
|
||||
quat.x = invView.m0 * quat.x + invView.m4 * quat.y + invView.m8 * quat.z + invView.m12 * quat.w;
|
||||
quat.y = invView.m1 * quat.x + invView.m5 * quat.y + invView.m9 * quat.z + invView.m13 * quat.w;
|
||||
quat.z = invView.m2 * quat.x + invView.m6 * quat.y + invView.m10 * quat.z + invView.m14 * quat.w;
|
||||
quat.w = invView.m3 * quat.x + invView.m7 * quat.y + invView.m11 * quat.z + invView.m15 * quat.w;
|
||||
|
||||
|
||||
vec.x /= quat.w;
|
||||
vec.y /= quat.w;
|
||||
vec.z /= quat.w;
|
||||
|
||||
|
||||
return vec;
|
||||
*/
|
||||
/*
|
||||
@ -1463,14 +1486,14 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
|
||||
quat.y = ((source.y - (float)y)/(float)height*2.0) - 1.0f;
|
||||
quat.z = 2.0*source.z - 1.0;
|
||||
quat.w = 1.0;
|
||||
|
||||
|
||||
// Traspose quaternion and multiply
|
||||
Quaternion result;
|
||||
result.x = modelviewprojection.m0 * quad.x + modelviewprojection.m4 * quad.y + modelviewprojection.m8 * quad.z + modelviewprojection.m12 * quad.w;
|
||||
result.y = modelviewprojection.m1 * quad.x + modelviewprojection.m5 * quad.y + modelviewprojection.m9 * quad.z + modelviewprojection.m13 * quad.w;
|
||||
result.z = modelviewprojection.m2 * quad.x + modelviewprojection.m6 * quad.y + modelviewprojection.m10 * quad.z + modelviewprojection.m14 * quad.w;
|
||||
result.w = modelviewprojection.m3 * quad.x + modelviewprojection.m7 * quad.y + modelviewprojection.m11 * quad.z + modelviewprojection.m15 * quad.w;
|
||||
|
||||
|
||||
// Invert
|
||||
result.w = 1.0f / result.w;
|
||||
|
||||
@ -1488,47 +1511,65 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
|
||||
Quaternion rayClip;
|
||||
Quaternion rayEye;
|
||||
Vector3 rayWorld;
|
||||
|
||||
|
||||
// Getting normal device coordinates
|
||||
float x = (2.0 * mousePosition.x) / GetScreenWidth() - 1.0;
|
||||
float y = 1.0 - (2.0 * mousePosition.y) / GetScreenHeight();
|
||||
float z = 1.0;
|
||||
normalDeviceCoordinates = (Vector3){ x, y, z };
|
||||
|
||||
|
||||
// Getting clip vector
|
||||
rayClip = (Quaternion){ normalDeviceCoordinates.x, normalDeviceCoordinates.y, -1, 1 };
|
||||
|
||||
|
||||
Matrix invProjection = projection;
|
||||
MatrixInvert(&invProjection);
|
||||
|
||||
|
||||
rayEye = MatrixQuaternionMultiply(invProjection, rayClip);
|
||||
rayEye = (Quaternion){ rayEye.x, rayEye.y, -1, 0 };
|
||||
|
||||
|
||||
Matrix invModelview = modelview;
|
||||
MatrixInvert(&invModelview);
|
||||
|
||||
|
||||
rayWorld = MatrixVector3Multiply(invModelview, (Vector3){rayEye.x, rayEye.y, rayEye.z} );
|
||||
VectorNormalize(&rayWorld);
|
||||
|
||||
|
||||
return rayWorld;
|
||||
*/
|
||||
return (Vector3){ 0, 0, 0 };
|
||||
}
|
||||
|
||||
// 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;
|
||||
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);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
|
||||
// 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
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead 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_S, GL_CLAMP_TO_EDGE); // Set texture to clamp on x-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;
|
||||
|
||||
@ -1542,6 +1583,8 @@ unsigned int rlglLoadTexture(unsigned char *data, int width, int height, int col
|
||||
genMipmaps = false;
|
||||
}
|
||||
|
||||
// TODO: Support mipmaps --> if (mipmapCount > 1)
|
||||
|
||||
// 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
|
||||
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);
|
||||
#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: 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)
|
||||
// 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
|
||||
|
||||
// Support for multiple color modes (16bit color modes and grayscale)
|
||||
// (sized)internalFormat format type
|
||||
// GL_R GL_RED GL_UNSIGNED_BYTE
|
||||
// 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_RGBA8 GL_RGBA GL_UNSIGNED_BYTE
|
||||
// GL_RGB8 GL_RGB GL_UNSIGNED_BYTE
|
||||
// GL_RGBA8 GL_RGBA 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 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;
|
||||
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;
|
||||
case R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break;
|
||||
default: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break;
|
||||
case UNCOMPRESSED_GRAYSCALE:
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, (unsigned char *)data);
|
||||
|
||||
// With swizzleMask we define how a one channel texture will be mapped to RGBA
|
||||
// Required GL >= 3.3 or EXT_texture_swizzle/ARB_texture_swizzle
|
||||
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
|
||||
TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically for new texture", id);
|
||||
@ -1638,13 +1722,15 @@ Model rlglLoadModel(VertexData mesh)
|
||||
Model model;
|
||||
|
||||
model.mesh = mesh;
|
||||
model.transform = MatrixIdentity();
|
||||
|
||||
#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.vaoId = 0; // Vertex Array Object
|
||||
model.vboId[0] = 0; // Vertex position VBO
|
||||
model.vboId[1] = 0; // Texcoords VBO
|
||||
model.vboId[2] = 0; // Normals VBO
|
||||
model.shader.id = 0; // No shader used
|
||||
|
||||
#elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
model.texture.id = whiteTexture; // Default whiteTexture
|
||||
@ -1681,109 +1767,31 @@ Model rlglLoadModel(VertexData mesh)
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.normals, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(simpleShader.normalLoc);
|
||||
glVertexAttribPointer(simpleShader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
|
||||
model.shader = simpleShader; // By default, simple shader will be used
|
||||
|
||||
model.vboId[0] = vertexBuffer[0]; // Vertex position VBO
|
||||
model.vboId[1] = vertexBuffer[1]; // Texcoords VBO
|
||||
model.vboId[2] = vertexBuffer[2]; // Normals VBO
|
||||
model.mesh.vboId[0] = vertexBuffer[0]; // Vertex position VBO
|
||||
model.mesh.vboId[1] = vertexBuffer[1]; // Texcoords VBO
|
||||
model.mesh.vboId[2] = vertexBuffer[2]; // Normals VBO
|
||||
|
||||
if (vaoSupported)
|
||||
{
|
||||
if (vaoModel > 0)
|
||||
{
|
||||
model.vaoId = vaoModel;
|
||||
model.mesh.vaoId = 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(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
|
||||
|
||||
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)
|
||||
// Load a shader (vertex shader + fragment shader) from text data
|
||||
@ -1801,7 +1809,7 @@ unsigned int rlglLoadShader(char *vShaderStr, char *fShaderStr)
|
||||
|
||||
glShaderSource(vertexShader, 1, &pvs, NULL);
|
||||
glShaderSource(fragmentShader, 1, &pfs, NULL);
|
||||
|
||||
|
||||
GLint success = 0;
|
||||
|
||||
glCompileShader(vertexShader);
|
||||
@ -1869,9 +1877,9 @@ unsigned int rlglLoadShader(char *vShaderStr, char *fShaderStr)
|
||||
glGetProgramInfoLog(program, maxLength, &length, log);
|
||||
|
||||
TraceLog(INFO, "%s", log);
|
||||
|
||||
|
||||
glDeleteProgram(program);
|
||||
|
||||
|
||||
program = 0;
|
||||
}
|
||||
else TraceLog(INFO, "[SHDR ID %i] Shader program loaded successfully", program);
|
||||
@ -1907,12 +1915,12 @@ unsigned char *rlglReadScreenPixels(int width, int height)
|
||||
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
|
||||
Shader LoadShader(char *vsFileName, char *fsFileName)
|
||||
{
|
||||
Shader shader;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// Shaders loading from external text file
|
||||
char *vShaderStr = TextFileRead(vsFileName);
|
||||
char *fShaderStr = TextFileRead(fsFileName);
|
||||
@ -1932,7 +1940,7 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
|
||||
shader.texcoordLoc = glGetAttribLocation(shader.id, "vertexTexCoord");
|
||||
shader.normalLoc = glGetAttribLocation(shader.id, "vertexNormal");
|
||||
// NOTE: custom shader does not use colorLoc
|
||||
|
||||
|
||||
// Get handles to GLSL uniform locations (vertex shader)
|
||||
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
|
||||
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
|
||||
@ -1941,35 +1949,39 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
|
||||
shader.textureLoc = glGetUniformLocation(shader.id, "texture0");
|
||||
shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor");
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
// Link shader to model
|
||||
void SetModelShader(Model *model, Shader shader)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
model->shader = shader;
|
||||
|
||||
if (vaoSupported) glBindVertexArray(model->vaoId);
|
||||
|
||||
if (vaoSupported) glBindVertexArray(model->mesh.vaoId);
|
||||
|
||||
// Enable vertex attributes: position
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->vboId[0]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[0]);
|
||||
glEnableVertexAttribArray(shader.vertexLoc);
|
||||
glVertexAttribPointer(shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
// Enable vertex attributes: texcoords
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->vboId[1]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[1]);
|
||||
glEnableVertexAttribArray(shader.texcoordLoc);
|
||||
glVertexAttribPointer(shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
// Enable vertex attributes: normals
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->vboId[2]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[2]);
|
||||
glEnableVertexAttribArray(shader.normalLoc);
|
||||
glVertexAttribPointer(shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
if (vaoSupported) glBindVertexArray(0); // Unbind VAO
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
void PrintProjectionMatrix()
|
||||
{
|
||||
PrintMatrix(projection);
|
||||
@ -1979,7 +1991,6 @@ void PrintModelviewMatrix()
|
||||
{
|
||||
PrintMatrix(modelview);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -1987,20 +1998,55 @@ void PrintModelviewMatrix()
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
#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)
|
||||
// NOTE: This shader program is used only for batch buffers (lines, triangles, quads)
|
||||
static Shader LoadDefaultShader(void)
|
||||
{
|
||||
Shader shader;
|
||||
|
||||
|
||||
// NOTE: Shaders are written using GLSL 110 (desktop), that is equivalent to GLSL 100 on ES2
|
||||
// NOTE: Detected an error on ATI cards if defined #version 110 while OpenGL 3.3+
|
||||
// Just defined #version 330 despite shader is #version 110
|
||||
|
||||
// Vertex shader directly defined, no external file required
|
||||
#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)
|
||||
char vShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work!
|
||||
#endif
|
||||
@ -2020,7 +2066,7 @@ static Shader LoadDefaultShader(void)
|
||||
|
||||
// Fragment shader directly defined, no external file required
|
||||
#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)
|
||||
char fShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work!
|
||||
"precision mediump float; \n" // WebGL, required for emscripten
|
||||
@ -2037,14 +2083,14 @@ static Shader LoadDefaultShader(void)
|
||||
|
||||
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Default shader loaded successfully", shader.id);
|
||||
else TraceLog(WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id);
|
||||
|
||||
|
||||
// Get handles to GLSL input attibute locations
|
||||
//-------------------------------------------------------------------
|
||||
shader.vertexLoc = glGetAttribLocation(shader.id, "vertexPosition");
|
||||
shader.texcoordLoc = glGetAttribLocation(shader.id, "vertexTexCoord");
|
||||
shader.colorLoc = glGetAttribLocation(shader.id, "vertexColor");
|
||||
// NOTE: default shader does not use normalLoc
|
||||
|
||||
|
||||
// Get handles to GLSL uniform locations (vertex shader)
|
||||
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
|
||||
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
|
||||
@ -2061,7 +2107,7 @@ static Shader LoadDefaultShader(void)
|
||||
static Shader LoadSimpleShader(void)
|
||||
{
|
||||
Shader shader;
|
||||
|
||||
|
||||
// NOTE: Shaders are written using GLSL 110 (desktop), that is equivalent to GLSL 100 on ES2
|
||||
// NOTE: Detected an error on ATI cards if defined #version 110 while OpenGL 3.3+
|
||||
// Just defined #version 330 despite shader is #version 110
|
||||
@ -2103,14 +2149,14 @@ static Shader LoadSimpleShader(void)
|
||||
|
||||
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Simple shader loaded successfully", shader.id);
|
||||
else TraceLog(WARNING, "[SHDR ID %i] Simple shader could not be loaded", shader.id);
|
||||
|
||||
|
||||
// Get handles to GLSL input attibute locations
|
||||
//-------------------------------------------------------------------
|
||||
shader.vertexLoc = glGetAttribLocation(shader.id, "vertexPosition");
|
||||
shader.texcoordLoc = glGetAttribLocation(shader.id, "vertexTexCoord");
|
||||
shader.normalLoc = glGetAttribLocation(shader.id, "vertexNormal");
|
||||
// NOTE: simple shader does not use colorLoc
|
||||
|
||||
|
||||
// Get handles to GLSL uniform locations (vertex shader)
|
||||
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
|
||||
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
|
||||
|
63
src/rlgl.h
63
src/rlgl.h
@ -88,35 +88,47 @@ typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
|
||||
|
||||
typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||
|
||||
typedef enum { GRAYSCALE = 0, R5G6B5, R8G8B8, R5G5B5A1, R4G4B4A4, R8G8B8A8 } ColorMode;
|
||||
|
||||
#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
|
||||
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
|
||||
typedef struct VertexData {
|
||||
int vertexCount;
|
||||
float *vertices; // 3 components per vertex
|
||||
float *texcoords; // 2 components per vertex
|
||||
float *normals; // 3 components per vertex
|
||||
unsigned char *colors;
|
||||
unsigned int vaoId;
|
||||
unsigned int vboId[4];
|
||||
} VertexData;
|
||||
|
||||
// Texture2D type
|
||||
typedef struct Texture2D {
|
||||
unsigned int id; // Texture id
|
||||
int width;
|
||||
int height;
|
||||
} Texture2D;
|
||||
|
||||
// Shader type
|
||||
typedef struct Shader {
|
||||
unsigned int id; // Shader program id
|
||||
|
||||
|
||||
// Variable attributes
|
||||
unsigned int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
unsigned int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
unsigned int normalLoc; // Normal attribute location point (vertex shader)
|
||||
unsigned int colorLoc; // Color attibute location point (vertex shader)
|
||||
|
||||
|
||||
// Uniforms
|
||||
unsigned int projectionLoc; // Projection matrix uniform location point (vertex shader)
|
||||
unsigned int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
|
||||
@ -125,15 +137,19 @@ typedef enum { GRAYSCALE = 0, R5G6B5, R8G8B8, R5G5B5A1, R4G4B4A4, R8G8B8A8 } Col
|
||||
} Shader;
|
||||
|
||||
// 3d Model type
|
||||
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
unsigned int vaoId;
|
||||
unsigned int vboId[4];
|
||||
Matrix transform;
|
||||
Texture2D texture;
|
||||
Shader shader;
|
||||
//Matrix transform;
|
||||
} Model;
|
||||
|
||||
// Texture2D type
|
||||
typedef struct Texture2D {
|
||||
unsigned int id; // Texture id
|
||||
int width;
|
||||
int height;
|
||||
} Texture2D;
|
||||
#endif
|
||||
|
||||
#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 rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
|
||||
int rlGetVersion(void); // Returns current OpenGL version
|
||||
void rlEnableFBO(void);
|
||||
void rlEnableFBO(void); // Enable rendering to postprocessing FBO
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration - rlgl functionality
|
||||
//------------------------------------------------------------------------------------
|
||||
void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...)
|
||||
void rlglInitPostpro(void); // Initialize postprocessing system
|
||||
void rlglClose(void); // De-init rlgl
|
||||
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)
|
||||
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 rlglLoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int format);
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
unsigned int rlglLoadShader(char *vShaderStr, char *fShaderStr); // Load a shader from text data
|
||||
#endif
|
||||
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps); // Load in GPU OpenGL texture
|
||||
unsigned int rlglLoadShader(char *vShaderStr, char *fShaderStr); // Load a shader from text data
|
||||
void rlglInitPostpro(void); // Initialize postprocessing system
|
||||
void rlglDrawPostpro(void); // Draw with postprocessing shader
|
||||
void rlglSetPostproShader(Shader shader); // Set postprocessing shader
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
46
src/shapes.c
46
src/shapes.c
@ -98,7 +98,7 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
|
||||
// Draw a color-filled circle
|
||||
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
|
||||
@ -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)
|
||||
{
|
||||
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);
|
||||
rlVertex2i(centerX, centerY);
|
||||
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);
|
||||
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();
|
||||
}
|
||||
@ -122,12 +122,12 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
|
||||
void DrawCircleV(Vector2 center, float radius, Color color)
|
||||
{
|
||||
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);
|
||||
rlVertex2i(center.x, center.y);
|
||||
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)*radius, center.y + cos(DEG2RAD*i)*radius);
|
||||
rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
@ -139,10 +139,10 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
// 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+1)) * radius, centerY + cos(DEG2RAD*(i+1)) * radius);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
@ -201,7 +201,7 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
rlVertex2i(0, 0);
|
||||
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)*radius, cos(DEG2RAD*i)*radius);
|
||||
rlVertex2f(sin(DEG2RAD*(i + 360/sides))*radius, cos(DEG2RAD*(i + 360/sides))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
rlPopMatrix();
|
||||
@ -299,8 +299,8 @@ void DrawPolyEx(Vector2 *points, int numPoints, Color color)
|
||||
for (int i = 0; i < numPoints - 2; i++)
|
||||
{
|
||||
rlVertex2f(points[i].x, points[i].y);
|
||||
rlVertex2f(points[i+1].x, points[i+1].y);
|
||||
rlVertex2f(points[i+2].x, points[i+2].y);
|
||||
rlVertex2f(points[i + 1].x, points[i + 1].y);
|
||||
rlVertex2f(points[i + 2].x, points[i + 2].y);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
@ -318,7 +318,7 @@ void DrawPolyExLines(Vector2 *points, int numPoints, Color color)
|
||||
for (int i = 0; i < numPoints - 1; i++)
|
||||
{
|
||||
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();
|
||||
}
|
||||
@ -367,10 +367,10 @@ bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2)
|
||||
{
|
||||
bool collision = false;
|
||||
|
||||
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 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));
|
||||
|
||||
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;
|
||||
}
|
||||
@ -395,10 +395,10 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
|
||||
{
|
||||
bool collision = false;
|
||||
|
||||
float dx = abs((rec.x + rec.width / 2) - center.x);
|
||||
float dy = abs((rec.y + rec.height / 2) - center.y);
|
||||
float dx = abs((rec.x + rec.width/2) - center.x);
|
||||
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;
|
||||
}
|
||||
|
170
src/text.c
170
src/text.c
@ -30,10 +30,9 @@
|
||||
#include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
|
||||
#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 GetExtendion()
|
||||
#include "utils.h" // Required for function GetExtension()
|
||||
|
||||
// Following libs will be used on LoadTTF()
|
||||
// Following libs are used on LoadTTF()
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include "stb_rect_pack.h"
|
||||
@ -44,7 +43,7 @@
|
||||
//----------------------------------------------------------------------------------
|
||||
#define FONT_FIRST_CHAR 32
|
||||
#define MAX_FONTCHARS 128
|
||||
#define MAX_FORMATTEXT_LENGTH 50
|
||||
#define MAX_FORMATTEXT_LENGTH 64
|
||||
|
||||
#define BIT_CHECK(a,b) ((a) & (1<<(b)))
|
||||
|
||||
@ -82,7 +81,7 @@ extern void LoadDefaultFont(void)
|
||||
{
|
||||
// NOTE: Using UTF8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement
|
||||
// http://www.utf8-chartable.de/unicode-utf8-table.pl
|
||||
|
||||
|
||||
defaultFont.numChars = 224; // Number of chars included in our default font
|
||||
|
||||
Image image;
|
||||
@ -93,60 +92,60 @@ extern void LoadDefaultFont(void)
|
||||
// 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
|
||||
int defaultFontData[512] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200020, 0x0001b000, 0x00000000, 0x00000000, 0x8ef92520, 0x00020a00, 0x7dbe8000, 0x1f7df45f,
|
||||
0x4a2bf2a0, 0x0852091e, 0x41224000, 0x10041450, 0x2e292020, 0x08220812, 0x41222000, 0x10041450, 0x10f92020, 0x3efa084c, 0x7d22103c, 0x107df7de,
|
||||
0xe8a12020, 0x08220832, 0x05220800, 0x10450410, 0xa4a3f000, 0x08520832, 0x05220400, 0x10450410, 0xe2f92020, 0x0002085e, 0x7d3e0281, 0x107df41f,
|
||||
0x00200000, 0x8001b000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0000fbe, 0xfbf7e00f, 0x5fbf7e7d, 0x0050bee8, 0x440808a2, 0x0a142fe8, 0x50810285, 0x0050a048,
|
||||
0x49e428a2, 0x0a142828, 0x40810284, 0x0048a048, 0x10020fbe, 0x09f7ebaf, 0xd89f3e84, 0x0047a04f, 0x09e48822, 0x0a142aa1, 0x50810284, 0x0048a048,
|
||||
0x04082822, 0x0a142fa0, 0x50810285, 0x0050a248, 0x00008fbe, 0xfbf42021, 0x5f817e7d, 0x07d09ce8, 0x00008000, 0x00000fe0, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000c0180,
|
||||
0xdfbf4282, 0x0bfbf7ef, 0x42850505, 0x004804bf, 0x50a142c6, 0x08401428, 0x42852505, 0x00a808a0, 0x50a146aa, 0x08401428, 0x42852505, 0x00081090,
|
||||
0x5fa14a92, 0x0843f7e8, 0x7e792505, 0x00082088, 0x40a15282, 0x08420128, 0x40852489, 0x00084084, 0x40a16282, 0x0842022a, 0x40852451, 0x00088082,
|
||||
0xc0bf4282, 0xf843f42f, 0x7e85fc21, 0x3e0900bf, 0x00000000, 0x00000004, 0x00000000, 0x000c0180, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000402, 0x41482000, 0x00000000, 0x00000800,
|
||||
0x04000404, 0x4100203c, 0x00000000, 0x00000800, 0xf7df7df0, 0x514bef85, 0xbefbefbe, 0x04513bef, 0x14414500, 0x494a2885, 0xa28a28aa, 0x04510820,
|
||||
0xf44145f0, 0x474a289d, 0xa28a28aa, 0x04510be0, 0x14414510, 0x494a2884, 0xa28a28aa, 0x02910a00, 0xf7df7df0, 0xd14a2f85, 0xbefbe8aa, 0x011f7be0,
|
||||
0x00000000, 0x00400804, 0x20080000, 0x00000000, 0x00000000, 0x00600f84, 0x20080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xac000000, 0x00000f01, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x06000000, 0x24000000, 0x00000901, 0x00000000, 0x09108000,
|
||||
0x24fa28a2, 0x00000901, 0x00000000, 0x013e0000, 0x2242252a, 0x00000952, 0x00000000, 0x038a8000, 0x2422222a, 0x00000929, 0x00000000, 0x010a8000,
|
||||
0x2412252a, 0x00000901, 0x00000000, 0x010a8000, 0x24fbe8be, 0x00000901, 0x00000000, 0x0ebe8000, 0xac020000, 0x00000f01, 0x00000000, 0x00048000,
|
||||
0x0003e000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, 0x8443b80e, 0x00203a03,
|
||||
0x02bea080, 0xf0000020, 0xc452208a, 0x04202b02, 0xf8029122, 0x07f0003b, 0xe44b388e, 0x02203a02, 0x081e8a1c, 0x0411e92a, 0xf4420be0, 0x01248202,
|
||||
0xe8140414, 0x05d104ba, 0xe7c3b880, 0x00893a0a, 0x283c0e1c, 0x04500902, 0xc4400080, 0x00448002, 0xe8208422, 0x04500002, 0x80400000, 0x05200002,
|
||||
0x083e8e00, 0x04100002, 0x804003e0, 0x07000042, 0xf8008400, 0x07f00003, 0x80400000, 0x04000022, 0x00000000, 0x00000000, 0x80400000, 0x04000002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00800702, 0x1848a0c2, 0x84010000, 0x02920921, 0x01042642, 0x00005121, 0x42023f7f, 0x00291002,
|
||||
0xefc01422, 0x7efdfbf7, 0xefdfa109, 0x03bbbbf7, 0x28440f12, 0x42850a14, 0x20408109, 0x01111010, 0x28440408, 0x42850a14, 0x2040817f, 0x01111010,
|
||||
0xefc78204, 0x7efdfbf7, 0xe7cf8109, 0x011111f3, 0x2850a932, 0x42850a14, 0x2040a109, 0x01111010, 0x2850b840, 0x42850a14, 0xefdfbf79, 0x03bbbbf7,
|
||||
0x001fa020, 0x00000000, 0x00001000, 0x00000000, 0x00002070, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x08022800, 0x00012283, 0x02430802, 0x01010001, 0x8404147c, 0x20000144, 0x80048404, 0x00823f08, 0xdfbf4284, 0x7e03f7ef, 0x142850a1, 0x0000210a,
|
||||
0x50a14684, 0x528a1428, 0x142850a1, 0x03efa17a, 0x50a14a9e, 0x52521428, 0x142850a1, 0x02081f4a, 0x50a15284, 0x4a221428, 0xf42850a1, 0x03efa14b,
|
||||
0x50a16284, 0x4a521428, 0x042850a1, 0x0228a17a, 0xdfbf427c, 0x7e8bf7ef, 0xf7efdfbf, 0x03efbd0b, 0x00000000, 0x04000000, 0x00000000, 0x00000008,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200508, 0x00840400, 0x11458122, 0x00014210,
|
||||
0x00514294, 0x51420800, 0x20a22a94, 0x0050a508, 0x00200000, 0x00000000, 0x00050000, 0x08000000, 0xfefbefbe, 0xfbefbefb, 0xfbeb9114, 0x00fbefbe,
|
||||
0x20820820, 0x8a28a20a, 0x8a289114, 0x3e8a28a2, 0xfefbefbe, 0xfbefbe0b, 0x8a289114, 0x008a28a2, 0x228a28a2, 0x08208208, 0x8a289114, 0x088a28a2,
|
||||
0xfefbefbe, 0xfbefbefb, 0xfa2f9114, 0x00fbefbe, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 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,
|
||||
0xa28a28aa, 0x000022a8, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022e8, 0x00000000, 0x00000000, 0xbefbefbe, 0x00003e2f, 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, 0x00200020, 0x0001b000, 0x00000000, 0x00000000, 0x8ef92520, 0x00020a00, 0x7dbe8000, 0x1f7df45f,
|
||||
0x4a2bf2a0, 0x0852091e, 0x41224000, 0x10041450, 0x2e292020, 0x08220812, 0x41222000, 0x10041450, 0x10f92020, 0x3efa084c, 0x7d22103c, 0x107df7de,
|
||||
0xe8a12020, 0x08220832, 0x05220800, 0x10450410, 0xa4a3f000, 0x08520832, 0x05220400, 0x10450410, 0xe2f92020, 0x0002085e, 0x7d3e0281, 0x107df41f,
|
||||
0x00200000, 0x8001b000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0000fbe, 0xfbf7e00f, 0x5fbf7e7d, 0x0050bee8, 0x440808a2, 0x0a142fe8, 0x50810285, 0x0050a048,
|
||||
0x49e428a2, 0x0a142828, 0x40810284, 0x0048a048, 0x10020fbe, 0x09f7ebaf, 0xd89f3e84, 0x0047a04f, 0x09e48822, 0x0a142aa1, 0x50810284, 0x0048a048,
|
||||
0x04082822, 0x0a142fa0, 0x50810285, 0x0050a248, 0x00008fbe, 0xfbf42021, 0x5f817e7d, 0x07d09ce8, 0x00008000, 0x00000fe0, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000c0180,
|
||||
0xdfbf4282, 0x0bfbf7ef, 0x42850505, 0x004804bf, 0x50a142c6, 0x08401428, 0x42852505, 0x00a808a0, 0x50a146aa, 0x08401428, 0x42852505, 0x00081090,
|
||||
0x5fa14a92, 0x0843f7e8, 0x7e792505, 0x00082088, 0x40a15282, 0x08420128, 0x40852489, 0x00084084, 0x40a16282, 0x0842022a, 0x40852451, 0x00088082,
|
||||
0xc0bf4282, 0xf843f42f, 0x7e85fc21, 0x3e0900bf, 0x00000000, 0x00000004, 0x00000000, 0x000c0180, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000402, 0x41482000, 0x00000000, 0x00000800,
|
||||
0x04000404, 0x4100203c, 0x00000000, 0x00000800, 0xf7df7df0, 0x514bef85, 0xbefbefbe, 0x04513bef, 0x14414500, 0x494a2885, 0xa28a28aa, 0x04510820,
|
||||
0xf44145f0, 0x474a289d, 0xa28a28aa, 0x04510be0, 0x14414510, 0x494a2884, 0xa28a28aa, 0x02910a00, 0xf7df7df0, 0xd14a2f85, 0xbefbe8aa, 0x011f7be0,
|
||||
0x00000000, 0x00400804, 0x20080000, 0x00000000, 0x00000000, 0x00600f84, 0x20080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xac000000, 0x00000f01, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x06000000, 0x24000000, 0x00000901, 0x00000000, 0x09108000,
|
||||
0x24fa28a2, 0x00000901, 0x00000000, 0x013e0000, 0x2242252a, 0x00000952, 0x00000000, 0x038a8000, 0x2422222a, 0x00000929, 0x00000000, 0x010a8000,
|
||||
0x2412252a, 0x00000901, 0x00000000, 0x010a8000, 0x24fbe8be, 0x00000901, 0x00000000, 0x0ebe8000, 0xac020000, 0x00000f01, 0x00000000, 0x00048000,
|
||||
0x0003e000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, 0x8443b80e, 0x00203a03,
|
||||
0x02bea080, 0xf0000020, 0xc452208a, 0x04202b02, 0xf8029122, 0x07f0003b, 0xe44b388e, 0x02203a02, 0x081e8a1c, 0x0411e92a, 0xf4420be0, 0x01248202,
|
||||
0xe8140414, 0x05d104ba, 0xe7c3b880, 0x00893a0a, 0x283c0e1c, 0x04500902, 0xc4400080, 0x00448002, 0xe8208422, 0x04500002, 0x80400000, 0x05200002,
|
||||
0x083e8e00, 0x04100002, 0x804003e0, 0x07000042, 0xf8008400, 0x07f00003, 0x80400000, 0x04000022, 0x00000000, 0x00000000, 0x80400000, 0x04000002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00800702, 0x1848a0c2, 0x84010000, 0x02920921, 0x01042642, 0x00005121, 0x42023f7f, 0x00291002,
|
||||
0xefc01422, 0x7efdfbf7, 0xefdfa109, 0x03bbbbf7, 0x28440f12, 0x42850a14, 0x20408109, 0x01111010, 0x28440408, 0x42850a14, 0x2040817f, 0x01111010,
|
||||
0xefc78204, 0x7efdfbf7, 0xe7cf8109, 0x011111f3, 0x2850a932, 0x42850a14, 0x2040a109, 0x01111010, 0x2850b840, 0x42850a14, 0xefdfbf79, 0x03bbbbf7,
|
||||
0x001fa020, 0x00000000, 0x00001000, 0x00000000, 0x00002070, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x08022800, 0x00012283, 0x02430802, 0x01010001, 0x8404147c, 0x20000144, 0x80048404, 0x00823f08, 0xdfbf4284, 0x7e03f7ef, 0x142850a1, 0x0000210a,
|
||||
0x50a14684, 0x528a1428, 0x142850a1, 0x03efa17a, 0x50a14a9e, 0x52521428, 0x142850a1, 0x02081f4a, 0x50a15284, 0x4a221428, 0xf42850a1, 0x03efa14b,
|
||||
0x50a16284, 0x4a521428, 0x042850a1, 0x0228a17a, 0xdfbf427c, 0x7e8bf7ef, 0xf7efdfbf, 0x03efbd0b, 0x00000000, 0x04000000, 0x00000000, 0x00000008,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200508, 0x00840400, 0x11458122, 0x00014210,
|
||||
0x00514294, 0x51420800, 0x20a22a94, 0x0050a508, 0x00200000, 0x00000000, 0x00050000, 0x08000000, 0xfefbefbe, 0xfbefbefb, 0xfbeb9114, 0x00fbefbe,
|
||||
0x20820820, 0x8a28a20a, 0x8a289114, 0x3e8a28a2, 0xfefbefbe, 0xfbefbe0b, 0x8a289114, 0x008a28a2, 0x228a28a2, 0x08208208, 0x8a289114, 0x088a28a2,
|
||||
0xfefbefbe, 0xfbefbefb, 0xfa2f9114, 0x00fbefbe, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 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,
|
||||
0xa28a28aa, 0x000022a8, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022e8, 0x00000000, 0x00000000, 0xbefbefbe, 0x00003e2f, 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 };
|
||||
|
||||
int charsHeight = 10;
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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 };
|
||||
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,
|
||||
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,
|
||||
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 };
|
||||
|
||||
// Re-construct image from defaultFontData and generate OpenGL texture
|
||||
//----------------------------------------------------------------------
|
||||
@ -168,7 +167,7 @@ extern void LoadDefaultFont(void)
|
||||
|
||||
if (counter > 512) counter = 0; // Security check...
|
||||
}
|
||||
|
||||
|
||||
//FILE *myimage = fopen("default_font.raw", "wb");
|
||||
//fwrite(image.pixels, 1, 128*128*4, myimage);
|
||||
//fclose(myimage);
|
||||
@ -211,7 +210,7 @@ extern void LoadDefaultFont(void)
|
||||
|
||||
extern void UnloadDefaultFont(void)
|
||||
{
|
||||
rlDeleteTextures(defaultFont.texture.id);
|
||||
UnloadTexture(defaultFont.texture);
|
||||
free(defaultFont.charSet);
|
||||
}
|
||||
|
||||
@ -258,7 +257,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
// Unload SpriteFont from GPU memory
|
||||
void UnloadSpriteFont(SpriteFont spriteFont)
|
||||
{
|
||||
rlDeleteTextures(spriteFont.texture.id);
|
||||
UnloadTexture(spriteFont.texture);
|
||||
free(spriteFont.charSet);
|
||||
}
|
||||
|
||||
@ -284,54 +283,35 @@ 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)
|
||||
{
|
||||
int length = strlen(text);
|
||||
int positionX = (int)position.x;
|
||||
int offsetX = 0;
|
||||
float scaleFactor;
|
||||
unsigned char letter;
|
||||
|
||||
|
||||
Character c;
|
||||
|
||||
if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
|
||||
else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
|
||||
|
||||
rlEnableTexture(spriteFont.texture.id);
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
for(int i = 0; i < length; i++)
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if ((unsigned char)text[i] == 0xc2)
|
||||
{
|
||||
if ((unsigned char)text[i] == 0xc2)
|
||||
{
|
||||
letter = (unsigned char)text[i + 1];
|
||||
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);
|
||||
letter = (unsigned char)text[i + 1];
|
||||
c = spriteFont.charSet[letter - FONT_FIRST_CHAR];
|
||||
i++;
|
||||
}
|
||||
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'
|
||||
|
@ -51,10 +51,8 @@ typedef struct {
|
||||
unsigned char *data; // Image raw data
|
||||
int width; // Image base width
|
||||
int height; // Image base height
|
||||
//int bpp; // bytes per pixel
|
||||
//int components; // num color components
|
||||
int mipmaps; // Mipmap levels, 1 by default
|
||||
int compFormat; // Compressed data format, 0 if no compression
|
||||
int format; // Data format
|
||||
} ImageEx;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -134,7 +132,7 @@ Image LoadImage(const char *fileName)
|
||||
|
||||
ImageEx imageDDS = LoadDDS(fileName);
|
||||
|
||||
if (imageDDS.compFormat == 0)
|
||||
if (imageDDS.format == 0)
|
||||
{
|
||||
image.pixels = (Color *)malloc(imageDDS.width * imageDDS.height * sizeof(Color));
|
||||
image.width = imageDDS.width;
|
||||
@ -304,14 +302,7 @@ Texture2D LoadTexture(const char *fileName)
|
||||
{
|
||||
ImageEx image = LoadDDS(fileName);
|
||||
|
||||
if (image.compFormat == 0)
|
||||
{
|
||||
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.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps, false);
|
||||
|
||||
texture.width = image.width;
|
||||
texture.height = image.height;
|
||||
@ -325,7 +316,7 @@ Texture2D LoadTexture(const char *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.height = image.height;
|
||||
@ -352,7 +343,17 @@ Texture2D LoadTexture(const char *fileName)
|
||||
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
|
||||
// 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)
|
||||
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.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 };
|
||||
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
|
||||
@ -545,18 +546,6 @@ static ImageEx LoadDDS(const char *fileName)
|
||||
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" 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
|
||||
typedef struct {
|
||||
unsigned int size;
|
||||
@ -594,7 +583,7 @@ static ImageEx LoadDDS(const char *fileName)
|
||||
image.width = 0;
|
||||
image.height = 0;
|
||||
image.mipmaps = 0;
|
||||
image.compFormat = 0;
|
||||
image.format = 0;
|
||||
|
||||
FILE *ddsFile = fopen(fileName, "rb");
|
||||
|
||||
@ -626,8 +615,6 @@ static ImageEx LoadDDS(const char *fileName)
|
||||
|
||||
image.width = header.width;
|
||||
image.height = header.height;
|
||||
image.mipmaps = 1;
|
||||
image.compFormat = 0;
|
||||
|
||||
if (header.ddspf.flags == 0x40 && header.ddspf.rgbBitCount == 24) // DDS_RGB, no compressed
|
||||
{
|
||||
@ -649,8 +636,11 @@ static ImageEx LoadDDS(const char *fileName)
|
||||
*dest++ = 255;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(buffer);
|
||||
|
||||
image.mipmaps = 1;
|
||||
image.format = UNCOMPRESSED_R8G8B8;
|
||||
}
|
||||
else if (header.ddspf.flags == 0x41 && header.ddspf.rgbBitCount == 32) // DDS_RGBA, no compressed
|
||||
{
|
||||
@ -659,18 +649,20 @@ static ImageEx LoadDDS(const char *fileName)
|
||||
fread(image.data, image.width*image.height*4, 1, ddsFile);
|
||||
|
||||
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 compressed files require OpenGL 3.2+ or ES 2.0", 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);
|
||||
|
||||
int bufsize;
|
||||
|
||||
// Calculate data size, including all mipmaps
|
||||
if (header.mipMapCount > 1) bufsize = header.pitchOrLinearSize * 2;
|
||||
else bufsize = header.pitchOrLinearSize;
|
||||
|
||||
TraceLog(DEBUG, "Pitch or linear size: %i", header.pitchOrLinearSize);
|
||||
|
||||
image.data = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
|
||||
|
||||
@ -680,19 +672,18 @@ static ImageEx LoadDDS(const char *fileName)
|
||||
fclose(ddsFile);
|
||||
|
||||
image.mipmaps = header.mipMapCount;
|
||||
image.compFormat = 0;
|
||||
|
||||
switch(header.ddspf.fourCC)
|
||||
{
|
||||
case FOURCC_DXT1: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
|
||||
case FOURCC_DXT3: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
|
||||
case FOURCC_DXT5: image.compFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
|
||||
case FOURCC_DXT1:
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// 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):
|
||||
//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):
|
||||
//GL_COMPRESSED_RGB8_ETC2
|
||||
//GL_COMPRESSED_RGBA8_ETC2
|
||||
@ -780,7 +767,7 @@ static ImageEx LoadPKM(const char *fileName)
|
||||
image.width = width;
|
||||
image.height = height;
|
||||
image.mipmaps = 1;
|
||||
image.compFormat = GL_ETC1_RGB8_OES;
|
||||
image.format = COMPRESSED_ETC1_RGB;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user