commit
8b3a82688e
@ -23,13 +23,13 @@ int main()
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = {{ 7.0, 7.0, 7.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
|
||||
|
||||
Image img = LoadImage("resources/cubicmap.png"); // Load cubesmap image (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(img, false); // Convert image to texture (VRAM)
|
||||
Model map = LoadCubicmap(img); // Load cubicmap model
|
||||
Image image = LoadImage("resources/cubicmap.png"); // Load cubesmap image (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM)
|
||||
Model map = LoadCubicmap(image); // Load cubicmap model (generate model from image)
|
||||
SetModelTexture(&map, texture); // Bind texture to model
|
||||
Vector3 mapPosition = { -1, 0.0, -1 }; // Set model position
|
||||
|
||||
UnloadImage(img); // Unload cubesmap image from RAM, already uploaded to VRAM
|
||||
UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
@ -23,13 +23,13 @@ int main()
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = {{ 10.0, 12.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
|
||||
|
||||
Image img = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(img, false); // Convert image to texture (VRAM)
|
||||
Model map = LoadHeightmap(img, 4); // Load heightmap model
|
||||
Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM)
|
||||
Model map = LoadHeightmap(image, 4); // Load heightmap model
|
||||
SetModelTexture(&map, texture); // Bind texture to model
|
||||
Vector3 mapPosition = { -4, 0.0, -4 }; // Set model position
|
||||
|
||||
UnloadImage(img); // Unload heightmap image from RAM, already uploaded to VRAM
|
||||
UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
@ -42,8 +42,7 @@ int main()
|
||||
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 4, 4 }, (Vector3){ 0, 45, 0 }, RED);
|
||||
//DrawPlaneEx((Vector3){ 0, 8, 0 }, (Vector2){ 2, 1 }, (Vector3){ 0, 0, 0 }, 4, 4, SKYBLUE);
|
||||
DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 4, 4 }, RED); // Draw a plane XZ
|
||||
|
||||
DrawGrid(10.0, 1.0);
|
||||
|
||||
|
@ -24,8 +24,8 @@ int main()
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - DDS texture loading and drawing");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
//Texture2D texture = LoadTexture("resources/raylib_logo.dds"); // Texture loading (compressed)
|
||||
Texture2D texture = LoadTexture("resources/raylib_logo_uncompressed.dds"); // Texture loading (uncompressed)
|
||||
|
||||
Texture2D texture = LoadTexture("resources/raylib_logo.dds"); // Texture loading (compressed)
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
@ -24,10 +24,10 @@ int main()
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
Image img = LoadImage("resources/raylib_logo.png"); // Loaded in CPU memory (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(img, false); // Image converted to texture, GPU memory (VRAM)
|
||||
Image image = LoadImage("resources/raylib_logo.png"); // Loaded in CPU memory (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
|
||||
|
||||
UnloadImage(img); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
||||
UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
|
@ -24,10 +24,10 @@ int main()
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture mipmaps generation");
|
||||
|
||||
// NOTE: To generate mipmaps for an image, image must be loaded first and converted to texture
|
||||
// with mipmaps option set to true on CreateTexture()
|
||||
|
||||
Image image = LoadImage("resources/raylib_logo.png"); // Load image to CPU memory (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image, true); // Create texture and generate mipmaps
|
||||
Texture2D texture = LoadTextureFromImage(image); // Load texture into GPU memory (VRAM)
|
||||
GenTextureMipmaps(texture); // Generate mipmaps for texture
|
||||
|
||||
UnloadImage(image); // Once texture has been created, we can unload image data from RAM
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
104
src/camera.c
104
src/camera.c
@ -23,7 +23,8 @@
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "camera.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -93,15 +94,6 @@ static int cameraMode = CAMERA_CUSTOM;
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static void ProcessCamera(Camera *camera, Vector3 *playerPosition);
|
||||
/*
|
||||
static void SetCameraControls(int front, int left, int back, right, up, down);
|
||||
static void SetMouseSensitivity(int sensitivity);
|
||||
static void SetResetPosition(Vector3 resetPosition);
|
||||
static void SetResetControl(int resetKey);
|
||||
static void SetPawnControl(int pawnControlKey);
|
||||
static void SetFnControl(int fnControlKey);
|
||||
static void SetSmoothZoomControl(int smoothZoomControlKey);
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
@ -153,6 +145,53 @@ Camera UpdateCamera(Vector3 *position)
|
||||
return internalCamera;
|
||||
}
|
||||
|
||||
|
||||
void SetCameraControls(int frontKey, int leftKey, int backKey, int rightKey, int upKey, int downKey)
|
||||
{
|
||||
cameraMovementController[0] = frontKey;
|
||||
cameraMovementController[1] = leftKey;
|
||||
cameraMovementController[2] = backKey;
|
||||
cameraMovementController[3] = rightKey;
|
||||
cameraMovementController[4] = upKey;
|
||||
cameraMovementController[5] = downKey;
|
||||
}
|
||||
|
||||
void SetCameraMouseSensitivity(float sensitivity)
|
||||
{
|
||||
mouseSensitivity = (sensitivity / 10000.0);
|
||||
}
|
||||
|
||||
void SetCameraResetPosition(Vector3 resetPosition)
|
||||
{
|
||||
resetingPosition = resetPosition;
|
||||
}
|
||||
|
||||
void SetCameraResetControl(int resetKey)
|
||||
{
|
||||
resetingKey = resetKey;
|
||||
}
|
||||
|
||||
void SetCameraPawnControl(int pawnControlKey)
|
||||
{
|
||||
pawnControllingKey = pawnControlKey;
|
||||
}
|
||||
|
||||
void SetCameraFnControl(int fnControlKey)
|
||||
{
|
||||
fnControllingKey = fnControlKey;
|
||||
}
|
||||
|
||||
void SetCameraSmoothZoomControl(int smoothZoomControlKey)
|
||||
{
|
||||
smoothZoomControllingKey = smoothZoomControlKey;
|
||||
}
|
||||
|
||||
void SetCameraOrbitalTarget(Vector3 target)
|
||||
{
|
||||
internalCamera.target = target;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -408,48 +447,3 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetCameraControls(int frontKey, int leftKey, int backKey, int rightKey, int upKey, int downKey)
|
||||
{
|
||||
cameraMovementController[0] = frontKey;
|
||||
cameraMovementController[1] = leftKey;
|
||||
cameraMovementController[2] = backKey;
|
||||
cameraMovementController[3] = rightKey;
|
||||
cameraMovementController[4] = upKey;
|
||||
cameraMovementController[5] = downKey;
|
||||
}
|
||||
|
||||
void SetMouseSensitivity(float sensitivity)
|
||||
{
|
||||
mouseSensitivity = (sensitivity / 10000.0);
|
||||
}
|
||||
|
||||
void SetResetPosition(Vector3 resetPosition)
|
||||
{
|
||||
resetingPosition = resetPosition;
|
||||
}
|
||||
|
||||
void SetResetControl(int resetKey)
|
||||
{
|
||||
resetingKey = resetKey;
|
||||
}
|
||||
|
||||
void SetPawnControl(int pawnControlKey)
|
||||
{
|
||||
pawnControllingKey = pawnControlKey;
|
||||
}
|
||||
|
||||
void SetFnControl(int fnControlKey)
|
||||
{
|
||||
fnControllingKey = fnControlKey;
|
||||
}
|
||||
|
||||
void SetSmoothZoomControl(int smoothZoomControlKey)
|
||||
{
|
||||
smoothZoomControllingKey = smoothZoomControlKey;
|
||||
}
|
||||
|
||||
void SetOrbitalTarget(Vector3 target)
|
||||
{
|
||||
internalCamera.target = target;
|
||||
}
|
||||
|
69
src/camera.h
Normal file
69
src/camera.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib Camera System - Camera Modes Setup and Control Functions
|
||||
*
|
||||
* Copyright (c) 2015 Marc Palau and Ramon Santamaria
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Camera modes
|
||||
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void SetCameraMode(int mode); // Select camera mode (multiple camera modes available)
|
||||
Camera UpdateCamera(Vector3 *position); // Update camera with position
|
||||
|
||||
void SetCameraControls(int front, int left, int back, int right, int up, int down);
|
||||
void SetCameraMouseSensitivity(float sensitivity);
|
||||
void SetCameraResetPosition(Vector3 resetPosition);
|
||||
void SetCameraResetControl(int resetKey);
|
||||
void SetCameraPawnControl(int pawnControlKey);
|
||||
void SetCameraFnControl(int fnControlKey);
|
||||
void SetCameraSmoothZoomControl(int smoothZoomControlKey);
|
||||
void SetCameraOrbitalTarget(Vector3 target);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CAMERA_H
|
46
src/core.c
46
src/core.c
@ -192,9 +192,6 @@ static double targetTime = 0.0; // Desired time for one frame, if 0
|
||||
static char configFlags = 0;
|
||||
static bool showLogo = false;
|
||||
|
||||
// Shaders variables
|
||||
static bool enabledPostpro = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Other Modules Functions Declaration (required by core)
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -468,7 +465,7 @@ int GetScreenHeight(void)
|
||||
// Sets Background Color
|
||||
void ClearBackground(Color color)
|
||||
{
|
||||
// TODO: Review "clearing area", full framebuffer vs render area
|
||||
// Clear full framebuffer (not only render area) to color
|
||||
rlClearColor(color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
@ -479,7 +476,7 @@ void BeginDrawing(void)
|
||||
updateTime = currentTime - previousTime;
|
||||
previousTime = currentTime;
|
||||
|
||||
if (enabledPostpro) rlEnableFBO();
|
||||
if (IsPosproShaderEnabled()) rlEnableFBO();
|
||||
|
||||
rlClearScreenBuffers();
|
||||
|
||||
@ -496,7 +493,7 @@ void EndDrawing(void)
|
||||
{
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
if (enabledPostpro) rlglDrawPostpro(); // Draw postprocessing effect (shader)
|
||||
if (IsPosproShaderEnabled()) rlglDrawPostpro(); // Draw postprocessing effect (shader)
|
||||
|
||||
SwapBuffers(); // Copy back buffer to front buffer
|
||||
|
||||
@ -606,7 +603,7 @@ Color GetColor(int hexValue)
|
||||
// Returns hexadecimal value for a Color
|
||||
int GetHexValue(Color color)
|
||||
{
|
||||
return ((color.a << 24) + (color.r << 16) + (color.g << 8) + color.b);
|
||||
return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
|
||||
}
|
||||
|
||||
// Returns a random value between min and max (both included)
|
||||
@ -970,39 +967,6 @@ Vector2 GetTouchPosition(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set postprocessing shader
|
||||
void SetPostproShader(Shader 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set custom shader to be used in batch draw
|
||||
void SetCustomShader(Shader shader)
|
||||
{
|
||||
rlglSetCustomShader(shader);
|
||||
}
|
||||
|
||||
// Set default shader to be used in batch draw
|
||||
void SetDefaultShader(void)
|
||||
{
|
||||
rlglSetDefaultShader();
|
||||
|
||||
enabledPostpro = false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -1579,7 +1543,7 @@ static void PollInputEvents(void)
|
||||
// Poll Events (registered events)
|
||||
// TODO: Enable/disable activityMinimized to block activity if minimized
|
||||
//while ((ident = ALooper_pollAll(activityMinimized ? 0 : -1, NULL, &events,(void**)&source)) >= 0)
|
||||
while ((ident = ALooper_pollAll(0, NULL, &events,(void**)&source)) >= 0)
|
||||
while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)
|
||||
{
|
||||
// Process this event
|
||||
if (source != NULL) source->process(app, source);
|
||||
|
@ -24,7 +24,6 @@
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdlib.h> // malloc(), free()
|
||||
@ -126,16 +125,17 @@ static float pinchDelta = 0;
|
||||
|
||||
// Detected gesture
|
||||
static int currentGesture = GESTURE_NONE;
|
||||
unsigned int enabledGestures = 0; // TODO: Currently not in use...
|
||||
|
||||
static Vector2 touchPosition;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
extern void ProcessMotionEvent(GestureEvent event);
|
||||
extern void ResetGestures(void);
|
||||
extern Vector2 GetRawPosition(void);
|
||||
|
||||
static void ProcessMotionEvent(GestureEvent event);
|
||||
static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude);
|
||||
static float OnPinch();
|
||||
static void SetDualInput(GestureEvent event);
|
||||
@ -185,40 +185,45 @@ int GetGestureType(void)
|
||||
return currentGesture;
|
||||
}
|
||||
|
||||
void SetGesturesEnabled(unsigned int gestureFlags)
|
||||
{
|
||||
enabledGestures = gestureFlags;
|
||||
}
|
||||
|
||||
// Get drag intensity (pixels per frame)
|
||||
float GetDragIntensity(void)
|
||||
float GetGestureDragIntensity(void)
|
||||
{
|
||||
return intensity;
|
||||
}
|
||||
|
||||
// Get drag angle
|
||||
// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
|
||||
float GetDragAngle(void)
|
||||
float GetGestureDragAngle(void)
|
||||
{
|
||||
return angle;
|
||||
}
|
||||
|
||||
// Get drag vector (between initial and final position)
|
||||
Vector2 GetDragVector(void)
|
||||
Vector2 GetGestureDragVector(void)
|
||||
{
|
||||
return dragVector;
|
||||
}
|
||||
|
||||
// Hold time measured in frames
|
||||
int GetHoldDuration(void)
|
||||
int GetGestureHoldDuration(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get magnitude between two pinch points
|
||||
float GetPinchDelta(void)
|
||||
float GetGesturePinchDelta(void)
|
||||
{
|
||||
return pinchDelta;
|
||||
}
|
||||
|
||||
// Get angle beween two pinch points
|
||||
// Get angle beween two pinch points
|
||||
// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
|
||||
float GetPinchAngle(void)
|
||||
float GetGesturePinchAngle(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -260,7 +265,7 @@ extern void InitAndroidGestures(struct android_app *app)
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
extern void ProcessMotionEvent(GestureEvent event)
|
||||
static void ProcessMotionEvent(GestureEvent event)
|
||||
{
|
||||
// Resets
|
||||
dragVector = (Vector2){ 0, 0 };
|
||||
@ -354,7 +359,7 @@ extern void ProcessMotionEvent(GestureEvent event)
|
||||
{
|
||||
lastDragPosition = endDragPosition;
|
||||
|
||||
endDragPosition = GetRawPosition();
|
||||
endDragPosition = touchPosition;
|
||||
|
||||
//endDragPosition.x = AMotionEvent_getX(event, 0);
|
||||
//endDragPosition.y = AMotionEvent_getY(event, 0);
|
||||
@ -417,7 +422,6 @@ extern void ProcessMotionEvent(GestureEvent event)
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
|
||||
|
||||
static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude)
|
||||
{
|
||||
float angle;
|
||||
@ -564,6 +568,18 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||
{
|
||||
//int32_t key = AKeyEvent_getKeyCode(event);
|
||||
//int32_t AKeyEvent_getMetaState(event);
|
||||
|
||||
int32_t code = AKeyEvent_getKeyCode((const AInputEvent *)event);
|
||||
|
||||
// If we are in active mode, we eat the back button and move into pause mode.
|
||||
// If we are already in pause mode, we allow the back button to be handled by the OS, which means we'll be shut down.
|
||||
/*
|
||||
if ((code == AKEYCODE_BACK) && mActiveMode)
|
||||
{
|
||||
setActiveMode(false);
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int32_t action = AMotionEvent_getAction(event);
|
||||
@ -585,7 +601,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||
|
||||
ProcessMotionEvent(gestureEvent);
|
||||
|
||||
return 0;
|
||||
return 0; // return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
76
src/models.c
76
src/models.c
@ -600,7 +600,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
||||
int mapX = heightmap.width;
|
||||
int mapZ = heightmap.height;
|
||||
|
||||
Color *heightmapPixels = GetPixelData(heightmap);
|
||||
Color *heightmapPixels = GetImageData(heightmap);
|
||||
|
||||
// NOTE: One vertex per pixel
|
||||
// TODO: Consider resolution when generating model data?
|
||||
@ -721,7 +721,7 @@ Model LoadCubicmap(Image cubicmap)
|
||||
{
|
||||
VertexData vData;
|
||||
|
||||
Color *cubicmapPixels = GetPixelData(cubicmap);
|
||||
Color *cubicmapPixels = GetImageData(cubicmap);
|
||||
|
||||
// Map cube size will be 1.0
|
||||
float mapCubeSide = 1.0f;
|
||||
@ -1105,8 +1105,6 @@ void UnloadModel(Model model)
|
||||
rlDeleteBuffers(model.mesh.vboId[2]);
|
||||
|
||||
rlDeleteVertexArrays(model.mesh.vaoId);
|
||||
//rlDeleteTextures(model.texture.id);
|
||||
//rlDeleteShader(model.shader.id);
|
||||
}
|
||||
|
||||
// Link a texture to a model
|
||||
@ -1114,8 +1112,9 @@ void SetModelTexture(Model *model, Texture2D texture)
|
||||
{
|
||||
if (texture.id <= 0)
|
||||
{
|
||||
model->texture.id = whiteTexture; // Default white texture (use mesh color)
|
||||
model->shader.texDiffuseId = whiteTexture;
|
||||
// Use default white texture (use mesh color)
|
||||
model->texture.id = whiteTexture; // OpenGL 1.1
|
||||
model->shader.texDiffuseId = whiteTexture; // OpenGL 3.3 / ES 2.0
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1124,26 +1123,6 @@ void SetModelTexture(Model *model, Texture2D texture)
|
||||
}
|
||||
}
|
||||
|
||||
// Load a custom shader (vertex shader + fragment shader)
|
||||
Shader LoadShader(char *vsFileName, char *fsFileName)
|
||||
{
|
||||
Shader shader = rlglLoadShader(vsFileName, fsFileName);
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
// Unload a custom shader from memory
|
||||
void UnloadShader(Shader shader)
|
||||
{
|
||||
rlDeleteShader(shader.id);
|
||||
}
|
||||
|
||||
// Set shader for a model
|
||||
void SetModelShader(Model *model, Shader shader)
|
||||
{
|
||||
rlglSetModelShader(model, shader);
|
||||
}
|
||||
|
||||
// Draw a model (with texture if set)
|
||||
void DrawModel(Model model, Vector3 position, float scale, Color tint)
|
||||
{
|
||||
@ -1269,7 +1248,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec
|
||||
rlDisableTexture();
|
||||
}
|
||||
|
||||
|
||||
// Detect collision between two spheres
|
||||
bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB)
|
||||
{
|
||||
bool collision = false;
|
||||
@ -1285,22 +1264,10 @@ bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, floa
|
||||
return collision;
|
||||
}
|
||||
|
||||
// Detect collision between two boxes
|
||||
// NOTE: Boxes are defined by two points minimum and maximum
|
||||
bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2)
|
||||
{
|
||||
/*
|
||||
// Get min and max vertex to construct bounds (AABB)
|
||||
Vector3 minVertex = tempVertices[0];
|
||||
Vector3 maxVertex = tempVertices[0];
|
||||
|
||||
for (int i = 1; i < tempVertices.Count; i++)
|
||||
{
|
||||
minVertex = Vector3.Min(minVertex, tempVertices[i]);
|
||||
maxVertex = Vector3.Max(maxVertex, tempVertices[i]);
|
||||
}
|
||||
|
||||
bounds = new BoundingBox(minVertex, maxVertex);
|
||||
*/
|
||||
|
||||
bool collision = true;
|
||||
|
||||
if ((maxBBox1.x >= minBBox2.x) && (minBBox1.x <= maxBBox2.x))
|
||||
@ -1313,6 +1280,7 @@ bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, V
|
||||
return collision;
|
||||
}
|
||||
|
||||
// Detect collision between box and sphere
|
||||
bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere)
|
||||
{
|
||||
bool collision = false;
|
||||
@ -1326,35 +1294,29 @@ bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSph
|
||||
{
|
||||
float dmin = 0;
|
||||
|
||||
if (centerSphere.x - minBBox.x <= radiusSphere)
|
||||
dmin += (centerSphere.x - minBBox.x) * (centerSphere.x - minBBox.x);
|
||||
else if (maxBBox.x - centerSphere.x <= radiusSphere)
|
||||
dmin += (centerSphere.x - maxBBox.x) * (centerSphere.x - maxBBox.x);
|
||||
if (centerSphere.x - minBBox.x <= radiusSphere) dmin += (centerSphere.x - minBBox.x)*(centerSphere.x - minBBox.x);
|
||||
else if (maxBBox.x - centerSphere.x <= radiusSphere) dmin += (centerSphere.x - maxBBox.x)*(centerSphere.x - maxBBox.x);
|
||||
|
||||
if (centerSphere.y - minBBox.y <= radiusSphere)
|
||||
dmin += (centerSphere.y - minBBox.y) * (centerSphere.y - minBBox.y);
|
||||
else if (maxBBox.y - centerSphere.y <= radiusSphere)
|
||||
dmin += (centerSphere.y - maxBBox.y) * (centerSphere.y - maxBBox.y);
|
||||
if (centerSphere.y - minBBox.y <= radiusSphere) dmin += (centerSphere.y - minBBox.y)*(centerSphere.y - minBBox.y);
|
||||
else if (maxBBox.y - centerSphere.y <= radiusSphere) dmin += (centerSphere.y - maxBBox.y)*(centerSphere.y - maxBBox.y);
|
||||
|
||||
if (centerSphere.z - minBBox.z <= radiusSphere)
|
||||
dmin += (centerSphere.z - minBBox.z) * (centerSphere.z - minBBox.z);
|
||||
else if (maxBBox.z - centerSphere.z <= radiusSphere)
|
||||
dmin += (centerSphere.z - maxBBox.z) * (centerSphere.z - maxBBox.z);
|
||||
if (centerSphere.z - minBBox.z <= radiusSphere) dmin += (centerSphere.z - minBBox.z)*(centerSphere.z - minBBox.z);
|
||||
else if (maxBBox.z - centerSphere.z <= radiusSphere) dmin += (centerSphere.z - maxBBox.z)*(centerSphere.z - maxBBox.z);
|
||||
|
||||
if (dmin <= radiusSphere * radiusSphere) collision = true;
|
||||
if (dmin <= radiusSphere*radiusSphere) collision = true;
|
||||
}
|
||||
|
||||
return collision;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// TODO: Useful function to check collision area?
|
||||
//BoundingBox GetCollisionArea(BoundingBox box1, BoundingBox box2)
|
||||
|
||||
// Detect and resolve cubicmap collisions
|
||||
// NOTE: player position (or camera) is modified inside this function
|
||||
Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius)
|
||||
{
|
||||
Color *cubicmapPixels = GetPixelData(cubicmap);
|
||||
Color *cubicmapPixels = GetImageData(cubicmap);
|
||||
|
||||
// Detect the cell where the player is located
|
||||
Vector3 impactDirection = { 0, 0, 0 };
|
||||
@ -1697,7 +1659,7 @@ static VertexData LoadOBJ(const char *fileName)
|
||||
|
||||
// Second reading pass: Get vertex data to fill intermediate arrays
|
||||
// NOTE: This second pass is required in case of multiple meshes defined in same OBJ
|
||||
// TODO: Consider that diferent meshes can have different vertex data available (position, texcoords, normals)
|
||||
// TODO: Consider that different meshes can have different vertex data available (position, texcoords, normals)
|
||||
while(!feof(objFile))
|
||||
{
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
123
src/raylib.h
123
src/raylib.h
@ -265,9 +265,6 @@ typedef struct Camera {
|
||||
Vector3 up;
|
||||
} Camera;
|
||||
|
||||
// Camera modes
|
||||
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 {
|
||||
@ -284,21 +281,21 @@ typedef struct VertexData {
|
||||
typedef struct Shader {
|
||||
unsigned int id; // Shader program id
|
||||
|
||||
// TODO: This should be Texture2D objects
|
||||
unsigned int texDiffuseId; // Diffuse texture id
|
||||
unsigned int texNormalId; // Normal texture id
|
||||
unsigned int texSpecularId; // Specular texture id
|
||||
|
||||
// Variable attributes
|
||||
int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
int normalLoc; // Normal attribute location point (vertex shader)
|
||||
int colorLoc; // Color attibute location point (vertex shader)
|
||||
int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
int normalLoc; // Normal attribute location point (vertex shader)
|
||||
int colorLoc; // Color attibute location point (vertex shader)
|
||||
|
||||
// Uniforms
|
||||
int projectionLoc; // Projection matrix uniform location point (vertex shader)
|
||||
int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
|
||||
|
||||
int tintColorLoc; // Color uniform location point (fragment shader)
|
||||
int projectionLoc; // Projection matrix uniform location point (vertex shader)
|
||||
int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
|
||||
int tintColorLoc; // Color uniform location point (fragment shader)
|
||||
|
||||
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader)
|
||||
int mapNormalLoc; // Normal map texture uniform location point (fragment shader)
|
||||
@ -358,18 +355,19 @@ typedef enum {
|
||||
} TextureFormat;
|
||||
|
||||
// Gestures type
|
||||
// NOTE: It could be used as flags to enable only some gestures
|
||||
typedef enum {
|
||||
GESTURE_NONE = 0,
|
||||
GESTURE_TAP,
|
||||
GESTURE_DOUBLETAP,
|
||||
GESTURE_HOLD,
|
||||
GESTURE_DRAG,
|
||||
GESTURE_SWIPE_RIGHT,
|
||||
GESTURE_SWIPE_LEFT,
|
||||
GESTURE_SWIPE_UP,
|
||||
GESTURE_SWIPE_DOWN,
|
||||
GESTURE_PINCH_IN,
|
||||
GESTURE_PINCH_OUT
|
||||
GESTURE_NONE = 1,
|
||||
GESTURE_TAP = 2,
|
||||
GESTURE_DOUBLETAP = 4,
|
||||
GESTURE_HOLD = 8,
|
||||
GESTURE_DRAG = 16,
|
||||
GESTURE_SWIPE_RIGHT = 32,
|
||||
GESTURE_SWIPE_LEFT = 64,
|
||||
GESTURE_SWIPE_UP = 128,
|
||||
GESTURE_SWIPE_DOWN = 256,
|
||||
GESTURE_PINCH_IN = 512,
|
||||
GESTURE_PINCH_OUT = 1024
|
||||
} Gestures;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -420,31 +418,28 @@ Color Fade(Color color, float alpha); // Color fade-in or
|
||||
void SetConfigFlags(char flags); // Enable some window configurations
|
||||
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
||||
|
||||
void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
|
||||
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
|
||||
void SetDefaultShader(void); // Set default shader to be used in batch draw
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera); // TODO: Gives the ray trace from mouse position
|
||||
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Gives the rayTrace from mouse position
|
||||
//------------------------------------------------------------------------------------
|
||||
// Shaders System Functions (Module: rlgl)
|
||||
// NOTE: This functions are useless when using OpenGL 1.1
|
||||
//------------------------------------------------------------------------------------
|
||||
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
|
||||
unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load a custom shader and return program id
|
||||
void UnloadShader(Shader shader); // Unload a custom shader from memory
|
||||
void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
|
||||
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
|
||||
void SetDefaultShader(void); // Set default shader to be used in batch draw
|
||||
void SetModelShader(Model *model, Shader shader); // Link a shader to a model
|
||||
bool IsPosproShaderEnabled(void); // Check if postprocessing shader is enabled
|
||||
|
||||
// Camera modes setup and control functions (module: camera)
|
||||
void SetCameraMode(int mode); // Select camera mode (multiple camera modes available)
|
||||
Camera UpdateCamera(Vector3 *position); // Update camera with position
|
||||
|
||||
void SetCameraControls(int front, int left, int back, int right, int up, int down);
|
||||
void SetMouseSensitivity(float sensitivity);
|
||||
void SetResetPosition(Vector3 resetPosition);
|
||||
void SetResetControl(int resetKey);
|
||||
void SetPawnControl(int pawnControlKey);
|
||||
void SetFnControl(int fnControlKey);
|
||||
void SetSmoothZoomControl(int smoothZoomControlKey);
|
||||
void SetOrbitalTarget(Vector3 target);
|
||||
|
||||
int GetShaderLocation(Shader shader, const char *uniformName);
|
||||
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size);
|
||||
|
||||
void SetShaderMapDiffuse(Shader *shader, Texture2D texture);
|
||||
void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture);
|
||||
void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture);
|
||||
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
||||
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
|
||||
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
|
||||
void SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment
|
||||
void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment
|
||||
void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment
|
||||
void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
@ -488,12 +483,14 @@ Vector2 GetTouchPosition(void); // Returns touch positio
|
||||
// Gestures System (module: gestures)
|
||||
bool IsGestureDetected(void);
|
||||
int GetGestureType(void);
|
||||
float GetDragIntensity(void);
|
||||
float GetDragAngle(void);
|
||||
Vector2 GetDragVector(void);
|
||||
int GetHoldDuration(void); // Hold time in frames
|
||||
float GetPinchDelta(void);
|
||||
float GetPinchAngle(void);
|
||||
void SetGesturesEnabled(unsigned int gestureFlags);
|
||||
|
||||
float GetGestureDragIntensity(void);
|
||||
float GetGestureDragAngle(void);
|
||||
Vector2 GetGestureDragVector(void);
|
||||
int GetGestureHoldDuration(void); // Hold time in frames
|
||||
float GetGesturePinchDelta(void);
|
||||
float GetGesturePinchAngle(void);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -530,16 +527,20 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2
|
||||
// Texture Loading and Drawing Functions (Module: textures)
|
||||
//------------------------------------------------------------------------------------
|
||||
Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
|
||||
Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit)
|
||||
Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file
|
||||
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
|
||||
Image LoadImageFromData(Color *pixels, int width, int height, int format); // Load image from Color array data
|
||||
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 LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount); // 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 LoadTextureFromImage(Image image); // Load a texture from image data (and generate mipmaps)
|
||||
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
|
||||
void ConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
||||
Color *GetPixelData(Image image); // Get pixel data from image as a Color struct array
|
||||
Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
|
||||
Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
|
||||
void ImageConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
||||
void ImageConvertFormat(Image *image, int newFormat); // Convert image data to desired format
|
||||
void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
|
||||
|
||||
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
|
||||
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
|
||||
@ -593,7 +594,6 @@ Model LoadHeightmap(Image heightmap, float maxHeight);
|
||||
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
|
||||
void UnloadModel(Model model); // Unload 3d model from memory
|
||||
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
||||
void SetModelShader(Model *model, Shader shader); // Link a shader to a model (not available on OpenGL 1.1)
|
||||
|
||||
void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||
void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||
@ -602,12 +602,9 @@ 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)
|
||||
void UnloadShader(Shader shader); // Unload a custom shader from memory
|
||||
|
||||
bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB);
|
||||
bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2);
|
||||
bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere);
|
||||
bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
|
||||
bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2); // Detect collision between two boxes
|
||||
bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
|
||||
Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Return the normal vector of the impacted surface
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
BIN
src/resources
BIN
src/resources
Binary file not shown.
564
src/rlgl.c
564
src/rlgl.c
@ -221,7 +221,7 @@ static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support
|
||||
static bool npotSupported = false; // NPOT textures full support
|
||||
|
||||
// Compressed textures support flags
|
||||
static bool texCompDXTSupported = false; // DDS texture compression support
|
||||
//static bool texCompDXTSupported = false; // DDS texture compression support
|
||||
static bool texCompETC1Supported = false; // ETC1 texture compression support
|
||||
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
|
||||
static bool texCompPVRTSupported = false; // PVR texture compression support
|
||||
@ -230,8 +230,14 @@ static bool texCompASTCSupported = false; // ASTC texture compression support
|
||||
// Framebuffer object and texture
|
||||
static GLuint fbo, fboColorTexture, fboDepthTexture;
|
||||
static Model postproQuad;
|
||||
|
||||
// Shaders related variables
|
||||
static bool enabledPostpro = false;
|
||||
#endif
|
||||
|
||||
// Compressed textures support flags
|
||||
static bool texCompDXTSupported = false; // DDS texture compression support
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: VAO functionality is exposed through extensions (OES)
|
||||
static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
|
||||
@ -263,7 +269,9 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight);
|
||||
static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight);
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
static char** StringSplit(char *baseString, const char delimiter, int *numExt);
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Matrix operations
|
||||
@ -952,7 +960,7 @@ void rlglInit(void)
|
||||
// Init default Shader (GLSL 110) -> Common for GL 3.3+ and ES2
|
||||
defaultShader = LoadDefaultShader();
|
||||
simpleShader = LoadSimpleShader();
|
||||
//customShader = rlglLoadShader("custom.vs", "custom.fs"); // Works ok
|
||||
//customShader = LoadShader("custom.vs", "custom.fs"); // Works ok
|
||||
|
||||
currentShader = defaultShader;
|
||||
|
||||
@ -967,7 +975,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, UNCOMPRESSED_R8G8B8A8, 1, false);
|
||||
whiteTexture = rlglLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1);
|
||||
|
||||
if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture loaded successfully", whiteTexture);
|
||||
else TraceLog(WARNING, "Base white texture could not be loaded");
|
||||
@ -1049,25 +1057,6 @@ void rlglInitPostpro(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set postprocessing shader
|
||||
void rlglSetPostproShader(Shader shader)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
rlglSetModelShader(&postproQuad, shader);
|
||||
|
||||
Texture2D texture;
|
||||
texture.id = fboColorTexture;
|
||||
texture.width = GetScreenWidth();
|
||||
texture.height = GetScreenHeight();
|
||||
|
||||
SetShaderMapDiffuse(&postproQuad.shader, texture);
|
||||
|
||||
//TraceLog(INFO, "Postproquad texture id: %i", postproQuad.texture.id);
|
||||
//TraceLog(INFO, "Postproquad shader diffuse map id: %i", postproQuad.shader.texDiffuseId);
|
||||
//TraceLog(INFO, "Shader diffuse map id: %i", shader.texDiffuseId);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Vertex Buffer Object deinitialization (memory free)
|
||||
void rlglClose(void)
|
||||
{
|
||||
@ -1372,7 +1361,18 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
|
||||
// Set shader textures (diffuse, normal, specular)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, model.shader.texDiffuseId);
|
||||
//glUniform1i(model.shader.mapDiffuseLoc, 0); // Diffuse texture fits in texture unit 0
|
||||
|
||||
if (model.shader.texNormalId != 0)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, model.shader.texNormalId);
|
||||
}
|
||||
|
||||
if (model.shader.texSpecularId != 0)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, model.shader.texSpecularId);
|
||||
}
|
||||
|
||||
if (vaoSupported)
|
||||
{
|
||||
@ -1397,9 +1397,21 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
|
||||
|
||||
// Draw call!
|
||||
glDrawArrays(GL_TRIANGLES, 0, model.mesh.vertexCount);
|
||||
|
||||
if (model.shader.texNormalId != 0)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
if (model.shader.texSpecularId != 0)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
||||
glActiveTexture(GL_TEXTURE0); // Set shader active texture to default 0
|
||||
glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
||||
|
||||
if (vaoSupported) glBindVertexArray(0); // Unbind VAO
|
||||
else glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind VBOs
|
||||
@ -1623,7 +1635,7 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
|
||||
}
|
||||
|
||||
// Convert image data to OpenGL texture (returns OpenGL valid Id)
|
||||
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps)
|
||||
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding
|
||||
|
||||
@ -1642,7 +1654,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
|
||||
TraceLog(WARNING, "DXT compressed texture format not supported");
|
||||
return id;
|
||||
}
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if ((!texCompETC1Supported) && (textureFormat == COMPRESSED_ETC1_RGB))
|
||||
{
|
||||
TraceLog(WARNING, "ETC1 compressed texture format not supported");
|
||||
@ -1666,7 +1678,8 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
|
||||
TraceLog(WARNING, "ASTC compressed texture format not supported");
|
||||
return id;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
glGenTextures(1, &id); // Generate Pointer to the texture
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
@ -1755,23 +1768,67 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if texture is power-of-two (POT) to enable mipmap generation
|
||||
bool texIsPOT = false;
|
||||
// Texture parameters configuration
|
||||
// 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_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
|
||||
|
||||
if (((width > 0) && ((width & (width - 1)) == 0)) && ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true;
|
||||
|
||||
if (genMipmaps && !texIsPOT)
|
||||
// Magnification and minification filters
|
||||
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
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
if (mipmapCount > 1)
|
||||
{
|
||||
TraceLog(WARNING, "[TEX ID %i] Texture is not power-of-two, mipmaps can not be generated", id);
|
||||
genMipmaps = false;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps (must be available)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Generate mipmaps if required
|
||||
// TODO: Improve mipmaps support
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
if (genMipmaps)
|
||||
// At this point we have the texture loaded in GPU and texture parameters configured
|
||||
|
||||
// NOTE: If mipmaps were not in data, they are not generated automatically
|
||||
|
||||
// Unbind current texture
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (id > 0) TraceLog(INFO, "[TEX ID %i] Texture created successfully (%ix%i)", id, width, height);
|
||||
else TraceLog(WARNING, "Texture could not be created");
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
// Generate mipmap data for selected texture
|
||||
void rlglGenerateMipmaps(unsigned int textureId)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
|
||||
// Check if texture is power-of-two (POT)
|
||||
bool texIsPOT = false;
|
||||
|
||||
// NOTE: In OpenGL ES 2.0 we have no way to retrieve texture size from id
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||
int width, height;
|
||||
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
|
||||
|
||||
if (((width > 0) && ((width & (width - 1)) == 0)) && ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true;
|
||||
#endif
|
||||
|
||||
if ((texIsPOT) || (npotSupported))
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
// Compute required mipmaps
|
||||
void *data = rlglReadTexturePixels(textureId, UNCOMPRESSED_R8G8B8A8); // TODO: Detect internal format
|
||||
|
||||
// NOTE: data size is reallocated to fit mipmaps data
|
||||
int mipmapCount = GenerateMipmaps(data, width, height);
|
||||
|
||||
@ -1794,48 +1851,19 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
|
||||
mipHeight /= 2;
|
||||
}
|
||||
|
||||
TraceLog(WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", id);
|
||||
}
|
||||
TraceLog(WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", textureId);
|
||||
|
||||
#elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if ((mipmapCount == 1) && (genMipmaps))
|
||||
{
|
||||
glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
|
||||
TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically for new texture", id);
|
||||
}
|
||||
#endif
|
||||
glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
|
||||
TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically", textureId);
|
||||
|
||||
// Texture parameters configuration
|
||||
// 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_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
|
||||
|
||||
// Magnification and minification filters
|
||||
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
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
if ((mipmapCount > 1) || (genMipmaps))
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps (must be available)
|
||||
}
|
||||
#endif
|
||||
|
||||
// At this point we have the texture loaded in GPU, with mipmaps generated (if desired) and texture parameters configured
|
||||
|
||||
// Unbind current texture
|
||||
}
|
||||
else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", textureId);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (id > 0) TraceLog(INFO, "[TEX ID %i] Texture created successfully (%ix%i)", id, width, height);
|
||||
else TraceLog(WARNING, "Texture could not be created");
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
// Load vertex data into a VAO (if supported) and VBO
|
||||
@ -1914,12 +1942,135 @@ Model rlglLoadModel(VertexData mesh)
|
||||
return model;
|
||||
}
|
||||
|
||||
// Read screen pixel data (color buffer)
|
||||
unsigned char *rlglReadScreenPixels(int width, int height)
|
||||
{
|
||||
unsigned char *screenData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4);
|
||||
|
||||
// NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData);
|
||||
|
||||
// Flip image vertically!
|
||||
unsigned char *imgData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4);
|
||||
|
||||
for (int y = height-1; y >= 0; y--)
|
||||
{
|
||||
for (int x = 0; x < (width*4); x++)
|
||||
{
|
||||
imgData[x + (height - y - 1)*width*4] = screenData[x + (y*width*4)];
|
||||
}
|
||||
}
|
||||
|
||||
free(screenData);
|
||||
|
||||
return imgData; // NOTE: image data should be freed
|
||||
}
|
||||
|
||||
// Read texture pixel data
|
||||
// NOTE: Retrieving pixel data from GPU not supported on OpenGL ES 2.0
|
||||
void *rlglReadTexturePixels(unsigned int textureId, unsigned int format)
|
||||
{
|
||||
void *pixels = NULL;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||
int width, height;
|
||||
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
|
||||
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
|
||||
//GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE
|
||||
|
||||
int glFormat = 0, glType = 0;
|
||||
|
||||
unsigned int size = width*height;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_LUMINANCE; glType = GL_UNSIGNED_BYTE; break; // 8 bit per pixel (no alpha)
|
||||
case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_LUMINANCE_ALPHA; glType = GL_UNSIGNED_BYTE; break; // 16 bpp (2 channels)
|
||||
case UNCOMPRESSED_R5G6B5: pixels = (unsigned short *)malloc(size); glFormat = GL_RGB; glType = GL_UNSIGNED_SHORT_5_6_5; break; // 16 bpp
|
||||
case UNCOMPRESSED_R8G8B8: pixels = (unsigned char *)malloc(size*3); glFormat = GL_RGB; glType = GL_UNSIGNED_BYTE; break; // 24 bpp
|
||||
case UNCOMPRESSED_R5G5B5A1: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_5_5_5_1; break; // 16 bpp (1 bit alpha)
|
||||
case UNCOMPRESSED_R4G4B4A4: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_4_4_4_4; break; // 16 bpp (4 bit alpha)
|
||||
case UNCOMPRESSED_R8G8B8A8: pixels = (unsigned char *)malloc(size*4); glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE; break; // 32 bpp
|
||||
default: TraceLog(WARNING, "Texture format not suported"); break;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
|
||||
// NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding.
|
||||
// Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting.
|
||||
// GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.)
|
||||
// GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.)
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#endif
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Shaders Functions
|
||||
// NOTE: Those functions are exposed directly to the user in raylib.h
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Load a custom shader and bind default locations
|
||||
Shader LoadShader(char *vsFileName, char *fsFileName)
|
||||
{
|
||||
Shader shader;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// Load a shader (vertex shader + fragment shader) from text data
|
||||
unsigned int rlglLoadShaderFromText(char *vShaderStr, char *fShaderStr)
|
||||
// Shaders loading from external text file
|
||||
char *vShaderStr = TextFileRead(vsFileName);
|
||||
char *fShaderStr = TextFileRead(fsFileName);
|
||||
|
||||
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
|
||||
|
||||
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Custom shader loaded successfully", shader.id);
|
||||
else TraceLog(WARNING, "[SHDR ID %i] Custom shader could not be loaded", shader.id);
|
||||
|
||||
// Shader strings must be freed
|
||||
free(vShaderStr);
|
||||
free(fShaderStr);
|
||||
|
||||
// Set shader textures ids (all 0 by default)
|
||||
shader.texDiffuseId = 0;
|
||||
shader.texNormalId = 0;
|
||||
shader.texSpecularId = 0;
|
||||
|
||||
// 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: custom shader does not use colorLoc
|
||||
shader.colorLoc = -1;
|
||||
|
||||
// Get handles to GLSL uniform locations (vertex shader)
|
||||
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
|
||||
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
|
||||
|
||||
// Get handles to GLSL uniform locations (fragment shader)
|
||||
shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor");
|
||||
shader.mapDiffuseLoc = glGetUniformLocation(shader.id, "texture0");
|
||||
shader.mapNormalLoc = -1; // It can be set later
|
||||
shader.mapSpecularLoc = -1; // It can be set later
|
||||
//--------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
// Load a custom shader and return program id
|
||||
unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr)
|
||||
{
|
||||
unsigned int program;
|
||||
unsigned int program = 0;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
GLuint vertexShader;
|
||||
GLuint fragmentShader;
|
||||
|
||||
@ -2010,113 +2161,18 @@ unsigned int rlglLoadShaderFromText(char *vShaderStr, char *fShaderStr)
|
||||
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
|
||||
#endif
|
||||
return program;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read screen pixel data (color buffer)
|
||||
unsigned char *rlglReadScreenPixels(int width, int height)
|
||||
// Unload a custom shader from memory
|
||||
void UnloadShader(Shader shader)
|
||||
{
|
||||
unsigned char *screenData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4);
|
||||
|
||||
// NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData);
|
||||
|
||||
// Flip image vertically!
|
||||
unsigned char *imgData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4);
|
||||
|
||||
for (int y = height-1; y >= 0; y--)
|
||||
{
|
||||
for (int x = 0; x < (width*4); x++)
|
||||
{
|
||||
imgData[x + (height - y - 1)*width*4] = screenData[x + (y*width*4)];
|
||||
}
|
||||
}
|
||||
|
||||
free(screenData);
|
||||
|
||||
return imgData; // NOTE: image data should be freed
|
||||
}
|
||||
|
||||
// Load a shader (vertex shader + fragment shader) from files
|
||||
Shader rlglLoadShader(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);
|
||||
|
||||
shader.id = rlglLoadShaderFromText(vShaderStr, fShaderStr);
|
||||
|
||||
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Custom shader loaded successfully", shader.id);
|
||||
else TraceLog(WARNING, "[SHDR ID %i] Custom shader could not be loaded", shader.id);
|
||||
|
||||
// Shader strings must be freed
|
||||
free(vShaderStr);
|
||||
free(fShaderStr);
|
||||
|
||||
// Set shader textures ids (all 0 by default)
|
||||
shader.texDiffuseId = 0;
|
||||
shader.texNormalId = 0;
|
||||
shader.texSpecularId = 0;
|
||||
|
||||
// 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: custom shader does not use colorLoc
|
||||
shader.colorLoc = -1;
|
||||
|
||||
// Get handles to GLSL uniform locations (vertex shader)
|
||||
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
|
||||
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
|
||||
|
||||
// Get handles to GLSL uniform locations (fragment shader)
|
||||
shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor");
|
||||
shader.mapDiffuseLoc = glGetUniformLocation(shader.id, "texture0");
|
||||
shader.mapNormalLoc = -1; // It can be set later
|
||||
shader.mapSpecularLoc = -1; // It can be set later
|
||||
//--------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
// Link shader to model
|
||||
void rlglSetModelShader(Model *model, Shader shader)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
model->shader = shader;
|
||||
|
||||
if (vaoSupported) glBindVertexArray(model->mesh.vaoId);
|
||||
|
||||
// Enable vertex attributes: position
|
||||
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->mesh.vboId[1]);
|
||||
glEnableVertexAttribArray(shader.texcoordLoc);
|
||||
glVertexAttribPointer(shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
// Enable vertex attributes: normals
|
||||
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
|
||||
|
||||
//if (model->texture.id > 0) model->shader.texDiffuseId = model->texture.id;
|
||||
#endif
|
||||
rlDeleteShader(shader.id);
|
||||
}
|
||||
|
||||
// Set custom shader to be used on batch draw
|
||||
void rlglSetCustomShader(Shader shader)
|
||||
void SetCustomShader(Shader shader)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if (currentShader.id != shader.id)
|
||||
@ -2148,39 +2204,131 @@ void rlglSetCustomShader(Shader shader)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set default shader to be used on batch draw
|
||||
void rlglSetDefaultShader(void)
|
||||
// Set postprocessing shader
|
||||
void SetPostproShader(Shader shader)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
rlglSetCustomShader(defaultShader);
|
||||
rlglSetPostproShader(defaultShader);
|
||||
if (!enabledPostpro)
|
||||
{
|
||||
enabledPostpro = true;
|
||||
rlglInitPostpro();
|
||||
}
|
||||
|
||||
SetModelShader(&postproQuad, shader);
|
||||
|
||||
Texture2D texture;
|
||||
texture.id = fboColorTexture;
|
||||
texture.width = GetScreenWidth();
|
||||
texture.height = GetScreenHeight();
|
||||
|
||||
SetShaderMapDiffuse(&postproQuad.shader, texture);
|
||||
|
||||
//TraceLog(DEBUG, "Postproquad texture id: %i", postproQuad.texture.id);
|
||||
//TraceLog(DEBUG, "Postproquad shader diffuse map id: %i", postproQuad.shader.texDiffuseId);
|
||||
//TraceLog(DEBUG, "Shader diffuse map id: %i", shader.texDiffuseId);
|
||||
#elif defined(GRAPHICS_API_OPENGL_11)
|
||||
TraceLog(WARNING, "Postprocessing shaders not supported on OpenGL 1.1");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set default shader to be used in batch draw
|
||||
void SetDefaultShader(void)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
SetCustomShader(defaultShader);
|
||||
SetPostproShader(defaultShader);
|
||||
|
||||
enabledPostpro = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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->mesh.vaoId);
|
||||
|
||||
// Enable vertex attributes: position
|
||||
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->mesh.vboId[1]);
|
||||
glEnableVertexAttribArray(shader.texcoordLoc);
|
||||
glVertexAttribPointer(shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
// Enable vertex attributes: normals
|
||||
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
|
||||
|
||||
//if (model->texture.id > 0) model->shader.texDiffuseId = model->texture.id;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check if postprocessing is enabled (used in module: core)
|
||||
bool IsPosproShaderEnabled(void)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
return enabledPostpro;
|
||||
#elif defined(GRAPHICS_API_OPENGL_11)
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get shader uniform location
|
||||
int GetShaderLocation(Shader shader, const char *uniformName)
|
||||
{
|
||||
int location = glGetUniformLocation(shader.id, uniformName);
|
||||
int location = -1;
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
location = glGetUniformLocation(shader.id, uniformName);
|
||||
|
||||
if (location == -1) TraceLog(WARNING, "[SHDR ID %i] Shader location for %s could not be found", shader.id, uniformName);
|
||||
|
||||
#endif
|
||||
return location;
|
||||
}
|
||||
|
||||
// Set shader uniform value (float)
|
||||
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glUseProgram(shader.id);
|
||||
|
||||
if (size == 1) glUniform1fv(uniformLoc, 1, value); // Shader uniform type: float
|
||||
else if (size == 2) glUniform2fv(uniformLoc, 1, value); // Shader uniform type: vec2
|
||||
else if (size == 3) glUniform3fv(uniformLoc, 1, value); // Shader uniform type: vec3
|
||||
else if (size == 4) glUniform4fv(uniformLoc, 1, value); // Shader uniform type: vec4
|
||||
else TraceLog(WARNING, "Shader value float array size not recognized");
|
||||
else TraceLog(WARNING, "Shader value float array size not supported");
|
||||
|
||||
glUseProgram(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set shader uniform value (int)
|
||||
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glUseProgram(shader.id);
|
||||
|
||||
if (size == 1) glUniform1iv(uniformLoc, 1, value); // Shader uniform type: int
|
||||
else if (size == 2) glUniform2iv(uniformLoc, 1, value); // Shader uniform type: ivec2
|
||||
else if (size == 3) glUniform3iv(uniformLoc, 1, value); // Shader uniform type: ivec3
|
||||
else if (size == 4) glUniform4iv(uniformLoc, 1, value); // Shader uniform type: ivec4
|
||||
else TraceLog(WARNING, "Shader value int array size not supported");
|
||||
|
||||
glUseProgram(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Default diffuse shader map texture assignment
|
||||
void SetShaderMapDiffuse(Shader *shader, Texture2D texture)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
shader->texDiffuseId = texture.id;
|
||||
|
||||
glUseProgram(shader->id);
|
||||
@ -2193,10 +2341,13 @@ void SetShaderMapDiffuse(Shader *shader, Texture2D texture)
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Normal map texture shader assignment
|
||||
void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
shader->mapNormalLoc = glGetUniformLocation(shader->id, uniformName);
|
||||
|
||||
if (shader->mapNormalLoc == -1) TraceLog(WARNING, "[SHDR ID %i] Shader location for %s could not be found", shader->id, uniformName);
|
||||
@ -2215,10 +2366,13 @@ void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D textu
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Specular map texture shader assignment
|
||||
void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
shader->mapSpecularLoc = glGetUniformLocation(shader->id, uniformName);
|
||||
|
||||
if (shader->mapSpecularLoc == -1) TraceLog(WARNING, "[SHDR ID %i] Shader location for %s could not be found", shader->id, uniformName);
|
||||
@ -2231,12 +2385,42 @@ void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D tex
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, shader->texSpecularId);
|
||||
|
||||
glUniform1i(shader->mapSpecularLoc, 2); // Texture fits in active texture unit 0
|
||||
glUniform1i(shader->mapSpecularLoc, 2); // Texture fits in active texture unit 2
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Generic shader maps assignment
|
||||
// TODO: Trying to find a generic shader to allow any kind of map
|
||||
// NOTE: mapLocation should be retrieved by user with GetShaderLocation()
|
||||
// ISSUE: mapTextureId: Shader should contain a reference to map texture and corresponding textureUnit,
|
||||
// so it can be automatically checked and used in rlglDrawModel()
|
||||
void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit)
|
||||
{
|
||||
/*
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if (mapLocation == -1) TraceLog(WARNING, "[SHDR ID %i] Map location could not be found", shader->id);
|
||||
else
|
||||
{
|
||||
shader->mapTextureId = texture.id;
|
||||
|
||||
glUseProgram(shader->id);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, shader->mapTextureId);
|
||||
|
||||
glUniform1i(mapLocation, textureUnit); // Texture fits in active textureUnit
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
@ -2345,7 +2529,7 @@ static Shader LoadDefaultShader(void)
|
||||
" gl_FragColor = texelColor*tintColor; \n"
|
||||
"} \n";
|
||||
|
||||
shader.id = rlglLoadShaderFromText(vShaderStr, fShaderStr);
|
||||
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
|
||||
|
||||
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);
|
||||
@ -2421,7 +2605,7 @@ static Shader LoadSimpleShader(void)
|
||||
" gl_FragColor = texelColor*tintColor; \n"
|
||||
"} \n";
|
||||
|
||||
shader.id = rlglLoadShaderFromText(vShaderStr, fShaderStr);
|
||||
shader.id = LoadShaderProgram(vShaderStr, fShaderStr);
|
||||
|
||||
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);
|
||||
@ -2640,7 +2824,7 @@ static void InitializeBuffersGPU(void)
|
||||
|
||||
// Update VBOs with vertex array data
|
||||
// NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
|
||||
// TODO: If no data changed on the CPU arrays --> No need to update GPU arrays
|
||||
// TODO: If no data changed on the CPU arrays --> No need to update GPU arrays (change flag required)
|
||||
static void UpdateBuffers(void)
|
||||
{
|
||||
if (lines.vCounter > 0)
|
||||
@ -2865,6 +3049,7 @@ void TraceLog(int msgType, const char *text, ...)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
static char **StringSplit(char *baseString, const char delimiter, int *numExt)
|
||||
{
|
||||
char **result = 0;
|
||||
@ -2913,4 +3098,5 @@ static char **StringSplit(char *baseString, const char delimiter, int *numExt)
|
||||
*numExt = (count - 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
18
src/rlgl.h
18
src/rlgl.h
@ -209,22 +209,22 @@ void rlglClose(void); // De-init rlgl
|
||||
void rlglDraw(void); // Draw VAO/VBO
|
||||
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
|
||||
|
||||
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps); // Load in GPU OpenGL texture
|
||||
Shader rlglLoadShader(char *vsFileName, char *fsFileName); // Load a shader (vertex shader + fragment shader) from files
|
||||
unsigned int rlglLoadShaderFromText(char *vShaderStr, char *fShaderStr); // Load a shader from text data
|
||||
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load in GPU OpenGL texture
|
||||
void rlglGenerateMipmaps(unsigned int textureId); // Generate mipmap data for selected texture
|
||||
|
||||
// NOTE: There is a set of shader related functions that are available to end user,
|
||||
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h
|
||||
|
||||
void rlglInitPostpro(void); // Initialize postprocessing system
|
||||
void rlglDrawPostpro(void); // Draw with postprocessing shader
|
||||
void rlglSetPostproShader(Shader shader); // Set postprocessing shader
|
||||
void rlglSetModelShader(Model *model, Shader shader); // Set shader for a model
|
||||
void rlglSetCustomShader(Shader shader); // Set custom shader to be used on batch draw
|
||||
void rlglSetDefaultShader(void); // Set default shader to be used on batch draw
|
||||
|
||||
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
|
||||
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)
|
||||
unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
|
||||
void *rlglReadTexturePixels(unsigned int textureId, unsigned int format); // Read texture pixel data
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
void PrintProjectionMatrix(void); // DEBUG: Print projection matrix
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* stb_image - v2.05 - public domain image loader - http://nothings.org/stb_image.h
|
||||
/* stb_image - v2.06 - public domain image loader - http://nothings.org/stb_image.h
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
Do this:
|
||||
@ -143,6 +143,7 @@
|
||||
|
||||
|
||||
Latest revision history:
|
||||
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
|
||||
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
|
||||
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
|
||||
2.03 (2015-04-12) additional corruption checking
|
||||
@ -5147,7 +5148,8 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
p = out+channel;
|
||||
if (channel >= channelCount) {
|
||||
// Fill this channel with default data.
|
||||
for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4;
|
||||
for (i = 0; i < pixelCount; i++, p += 4)
|
||||
*p = (channel == 3 ? 255 : 0);
|
||||
} else {
|
||||
// Read the RLE data.
|
||||
count = 0;
|
||||
@ -5193,11 +5195,12 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
p = out + channel;
|
||||
if (channel > channelCount) {
|
||||
// Fill this channel with default data.
|
||||
for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4;
|
||||
for (i = 0; i < pixelCount; i++, p += 4)
|
||||
*p = channel == 3 ? 255 : 0;
|
||||
} else {
|
||||
// Read the data.
|
||||
for (i = 0; i < pixelCount; i++)
|
||||
*p = stbi__get8(s), p += 4;
|
||||
for (i = 0; i < pixelCount; i++, p += 4)
|
||||
*p = stbi__get8(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5207,7 +5210,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
if (out == NULL) return out; // stbi__convert_format frees input on failure
|
||||
}
|
||||
|
||||
if (comp) *comp = channelCount;
|
||||
if (comp) *comp = 4;
|
||||
*y = h;
|
||||
*x = w;
|
||||
|
||||
@ -6300,6 +6303,7 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
||||
|
||||
/*
|
||||
revision history:
|
||||
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
|
||||
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
|
||||
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
|
||||
2.03 (2015-04-12) extra corruption checking (mmozeiko)
|
||||
|
18
src/text.c
18
src/text.c
@ -171,11 +171,12 @@ extern void LoadDefaultFont(void)
|
||||
//fwrite(image.pixels, 1, 128*128*4, myimage);
|
||||
//fclose(myimage);
|
||||
|
||||
Image image = LoadImageFromData(imagePixels, imWidth, imHeight, UNCOMPRESSED_GRAY_ALPHA);
|
||||
Image image = LoadImageEx(imagePixels, imWidth, imHeight);
|
||||
ImageConvertFormat(&image, UNCOMPRESSED_GRAY_ALPHA);
|
||||
|
||||
free(imagePixels);
|
||||
|
||||
defaultFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture
|
||||
defaultFont.texture = LoadTextureFromImage(image);
|
||||
UnloadImage(image);
|
||||
|
||||
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
|
||||
@ -237,10 +238,10 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
|
||||
// At this point we have a data array...
|
||||
|
||||
Color *imagePixels = GetPixelData(image);
|
||||
Color *imagePixels = GetImageData(image);
|
||||
|
||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
ConvertToPOT(&image, MAGENTA);
|
||||
ImageConvertToPOT(&image, MAGENTA);
|
||||
#endif
|
||||
// Process bitmap Font pixel data to get measures (Character array)
|
||||
// spriteFont.charSet data is filled inside the function and memory is allocated!
|
||||
@ -251,7 +252,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
|
||||
spriteFont.numChars = numChars;
|
||||
|
||||
spriteFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture
|
||||
spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture
|
||||
|
||||
free(imagePixels);
|
||||
UnloadImage(image);
|
||||
@ -556,13 +557,14 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||
counter++;
|
||||
}
|
||||
|
||||
Image image = LoadImageFromData(imagePixels, rbmfHeader.imgWidth, rbmfHeader.imgHeight, UNCOMPRESSED_GRAY_ALPHA);
|
||||
Image image = LoadImageEx(imagePixels, rbmfHeader.imgWidth, rbmfHeader.imgHeight);
|
||||
ImageConvertFormat(&image, UNCOMPRESSED_GRAY_ALPHA);
|
||||
|
||||
free(imagePixels);
|
||||
|
||||
TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
|
||||
|
||||
spriteFont.texture = LoadTextureFromImage(image, false);
|
||||
spriteFont.texture = LoadTextureFromImage(image);
|
||||
UnloadImage(image); // Unload image data
|
||||
|
||||
//TraceLog(INFO, "[%s] Starting charSet reconstruction", fileName);
|
||||
@ -689,7 +691,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize)
|
||||
*/
|
||||
font.numChars = 95;
|
||||
font.charSet = (Character *)malloc(font.numChars*sizeof(Character));
|
||||
font.texture = LoadTextureFromImage(image, false);
|
||||
font.texture = LoadTextureFromImage(image);
|
||||
|
||||
//stbtt_aligned_quad letter;
|
||||
//int x = 0, y = 0;
|
||||
|
516
src/textures.c
516
src/textures.c
@ -123,6 +123,82 @@ Image LoadImage(const char *fileName)
|
||||
return image;
|
||||
}
|
||||
|
||||
// Load image data from Color array data (RGBA - 32bit)
|
||||
Image LoadImageEx(Color *pixels, int width, int height)
|
||||
{
|
||||
Image image;
|
||||
image.data = NULL;
|
||||
image.width = width;
|
||||
image.height = height;
|
||||
image.mipmaps = 1;
|
||||
image.format = UNCOMPRESSED_R8G8B8A8;
|
||||
|
||||
int k = 0;
|
||||
|
||||
image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image.width*image.height*4; i += 4)
|
||||
{
|
||||
((unsigned char *)image.data)[i] = pixels[k].r;
|
||||
((unsigned char *)image.data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image.data)[i + 2] = pixels[k].b;
|
||||
((unsigned char *)image.data)[i + 3] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
// Load an image from RAW file
|
||||
Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize)
|
||||
{
|
||||
Image image;
|
||||
|
||||
image.data = NULL;
|
||||
image.width = 0;
|
||||
image.height = 0;
|
||||
image.mipmaps = 0;
|
||||
image.format = 0;
|
||||
|
||||
FILE *rawFile = fopen(fileName, "rb");
|
||||
|
||||
if (rawFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] RAW image file could not be opened", fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET);
|
||||
|
||||
unsigned int size = width*height;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case UNCOMPRESSED_GRAYSCALE: image.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha)
|
||||
case UNCOMPRESSED_GRAY_ALPHA: image.data = (unsigned char *)malloc(size*2); size *= 2; break; // 16 bpp (2 channels)
|
||||
case UNCOMPRESSED_R5G6B5: image.data = (unsigned short *)malloc(size); break; // 16 bpp
|
||||
case UNCOMPRESSED_R8G8B8: image.data = (unsigned char *)malloc(size*3); size *= 3; break; // 24 bpp
|
||||
case UNCOMPRESSED_R5G5B5A1: image.data = (unsigned short *)malloc(size); break; // 16 bpp (1 bit alpha)
|
||||
case UNCOMPRESSED_R4G4B4A4: image.data = (unsigned short *)malloc(size); break; // 16 bpp (4 bit alpha)
|
||||
case UNCOMPRESSED_R8G8B8A8: image.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp
|
||||
default: TraceLog(WARNING, "Image format not suported"); break;
|
||||
}
|
||||
|
||||
fread(image.data, size, 1, rawFile);
|
||||
|
||||
// TODO: Check if data have been read
|
||||
|
||||
image.width = width;
|
||||
image.height = height;
|
||||
image.mipmaps = 0;
|
||||
image.format = format;
|
||||
|
||||
fclose(rawFile);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
// Load an image from rRES file (raylib Resource)
|
||||
// TODO: Review function to support multiple color modes
|
||||
Image LoadImageFromRES(const char *rresName, int resId)
|
||||
@ -243,12 +319,12 @@ Texture2D LoadTexture(const char *fileName)
|
||||
Image image = LoadImage(fileName);
|
||||
|
||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
ConvertToPOT(&image, BLANK);
|
||||
ImageConvertToPOT(&image, BLANK);
|
||||
#endif
|
||||
|
||||
if (image.data != NULL)
|
||||
{
|
||||
texture = LoadTextureFromImage(image, false);
|
||||
texture = LoadTextureFromImage(image);
|
||||
UnloadImage(image);
|
||||
}
|
||||
else
|
||||
@ -261,7 +337,7 @@ Texture2D LoadTexture(const char *fileName)
|
||||
return texture;
|
||||
}
|
||||
|
||||
Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps)
|
||||
Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
@ -270,14 +346,26 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, in
|
||||
texture.mipmaps = mipmapCount;
|
||||
texture.format = textureFormat;
|
||||
|
||||
texture.id = rlglLoadTexture(data, width, height, textureFormat, mipmapCount, genMipmaps);
|
||||
texture.id = rlglLoadTexture(data, width, height, textureFormat, mipmapCount);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Load an image as texture from rRES file (raylib Resource)
|
||||
Texture2D LoadTextureFromRES(const char *rresName, int resId)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
Image image = LoadImageFromRES(rresName, resId);
|
||||
texture = LoadTextureFromImage(image);
|
||||
UnloadImage(image);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Load a texture from image data
|
||||
// NOTE: image is not unloaded, it must be done manually
|
||||
Texture2D LoadTextureFromImage(Image image, bool genMipmaps)
|
||||
Texture2D LoadTextureFromImage(Image image)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
@ -288,7 +376,7 @@ Texture2D LoadTextureFromImage(Image image, bool genMipmaps)
|
||||
texture.mipmaps = 0;
|
||||
texture.format = 0;
|
||||
|
||||
texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps, false);
|
||||
texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps);
|
||||
|
||||
texture.width = image.width;
|
||||
texture.height = image.height;
|
||||
@ -298,18 +386,6 @@ Texture2D LoadTextureFromImage(Image image, bool genMipmaps)
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Load an image as texture from rRES file (raylib Resource)
|
||||
Texture2D LoadTextureFromRES(const char *rresName, int resId)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
Image image = LoadImageFromRES(rresName, resId);
|
||||
texture = LoadTextureFromImage(image, false);
|
||||
UnloadImage(image);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Unload image from CPU memory (RAM)
|
||||
void UnloadImage(Image image)
|
||||
{
|
||||
@ -322,46 +398,8 @@ void UnloadTexture(Texture2D texture)
|
||||
rlDeleteTextures(texture.id);
|
||||
}
|
||||
|
||||
// Convert image to POT (power-of-two)
|
||||
// NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5)
|
||||
void ConvertToPOT(Image *image, Color fillColor)
|
||||
{
|
||||
// TODO: Review for new image struct
|
||||
/*
|
||||
// Just add the required amount of pixels at the right and bottom sides of image...
|
||||
int potWidth = GetNextPOT(image->width);
|
||||
int potHeight = GetNextPOT(image->height);
|
||||
|
||||
// Check if POT texture generation is required (if texture is not already POT)
|
||||
if ((potWidth != image->width) || (potHeight != image->height))
|
||||
{
|
||||
Color *imgDataPixelPOT = NULL;
|
||||
|
||||
// Generate POT array from NPOT data
|
||||
imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
|
||||
|
||||
for (int j = 0; j < potHeight; j++)
|
||||
{
|
||||
for (int i = 0; i < potWidth; i++)
|
||||
{
|
||||
if ((j < image->height) && (i < image->width)) imgDataPixelPOT[j*potWidth + i] = image->data[j*image->width + i];
|
||||
else imgDataPixelPOT[j*potWidth + i] = fillColor;
|
||||
}
|
||||
}
|
||||
|
||||
TraceLog(WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight);
|
||||
|
||||
free(image->pixels);
|
||||
|
||||
image->pixels = imgDataPixelPOT;
|
||||
image->width = potWidth;
|
||||
image->height = potHeight;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Get pixel data from image in the form of Color struct array
|
||||
Color *GetPixelData(Image image)
|
||||
Color *GetImageData(Image image)
|
||||
{
|
||||
Color *pixels = (Color *)malloc(image.width*image.height*sizeof(Color));
|
||||
|
||||
@ -447,144 +485,244 @@ Color *GetPixelData(Image image)
|
||||
return pixels;
|
||||
}
|
||||
|
||||
// Fill image data with pixels Color data (RGBA - 32bit)
|
||||
// NOTE: Data is transformed to desired format
|
||||
Image LoadImageFromData(Color *pixels, int width, int height, int format)
|
||||
// Get pixel data from GPU texture and return an Image
|
||||
Image GetTextureData(Texture2D texture)
|
||||
{
|
||||
Image image;
|
||||
image.data = NULL;
|
||||
image.width = width;
|
||||
image.height = height;
|
||||
image.mipmaps = 1;
|
||||
image.format = format;
|
||||
|
||||
int k = 0;
|
||||
|
||||
switch (format)
|
||||
image.data = rlglReadTexturePixels(texture.id, texture.format);
|
||||
|
||||
if (image.data != NULL)
|
||||
{
|
||||
case UNCOMPRESSED_GRAYSCALE:
|
||||
{
|
||||
image.data = (unsigned char *)malloc(image.width*image.height*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image.width*image.height; i++)
|
||||
{
|
||||
((unsigned char *)image.data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_GRAY_ALPHA:
|
||||
{
|
||||
image.data = (unsigned char *)malloc(image.width*image.height*2*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image.width*image.height*2; i += 2)
|
||||
{
|
||||
((unsigned char *)image.data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
|
||||
((unsigned char *)image.data)[i + 1] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R5G6B5:
|
||||
{
|
||||
image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short));
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
|
||||
for (int i = 0; i < image.width*image.height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*31/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*63/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*31/255));
|
||||
|
||||
((unsigned short *)image.data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R8G8B8:
|
||||
{
|
||||
image.data = (unsigned char *)malloc(image.width*image.height*3*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image.width*image.height*3; i += 3)
|
||||
{
|
||||
((unsigned char *)image.data)[i] = pixels[k].r;
|
||||
((unsigned char *)image.data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image.data)[i + 2] = pixels[k].b;
|
||||
k++;
|
||||
}
|
||||
} break;
|
||||
case UNCOMPRESSED_R5G5B5A1:
|
||||
{
|
||||
image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short));
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a = 1;
|
||||
|
||||
for (int i = 0; i < image.width*image.height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*31/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*31/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*31/255));
|
||||
a = (pixels[k].a > 50) ? 1 : 0;
|
||||
|
||||
((unsigned short *)image.data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1| (unsigned short)a;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R4G4B4A4:
|
||||
{
|
||||
image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short));
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
|
||||
for (int i = 0; i < image.width*image.height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*15/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*15/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*15/255));
|
||||
a = (unsigned char)(round((float)pixels[k].a*15/255));
|
||||
|
||||
((unsigned short *)image.data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R8G8B8A8:
|
||||
{
|
||||
image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image.width*image.height*4; i += 4)
|
||||
{
|
||||
((unsigned char *)image.data)[i] = pixels[k].r;
|
||||
((unsigned char *)image.data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image.data)[i + 2] = pixels[k].b;
|
||||
((unsigned char *)image.data)[i + 3] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
TraceLog(WARNING, "Format not recognized, image could not be loaded");
|
||||
|
||||
return image;
|
||||
} break;
|
||||
image.width = texture.width;
|
||||
image.height = texture.height;
|
||||
image.format = texture.format;
|
||||
image.mipmaps = 1;
|
||||
}
|
||||
|
||||
else TraceLog(WARNING, "Texture pixel data could not be obtained");
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
// Convert image data to desired format
|
||||
void ImageConvertFormat(Image *image, int newFormat)
|
||||
{
|
||||
if ((image->format != newFormat) && (image->format < 8) && (newFormat < 8))
|
||||
{
|
||||
Color *pixels = GetImageData(*image);
|
||||
|
||||
free(image->data);
|
||||
|
||||
image->format = newFormat;
|
||||
|
||||
int k = 0;
|
||||
|
||||
switch (image->format)
|
||||
{
|
||||
case UNCOMPRESSED_GRAYSCALE:
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_GRAY_ALPHA:
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*2*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image->width*image->height*2; i += 2)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R5G6B5:
|
||||
{
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*31/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*63/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*31/255));
|
||||
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R8G8B8:
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*3*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image->width*image->height*3; i += 3)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = pixels[k].r;
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image->data)[i + 2] = pixels[k].b;
|
||||
k++;
|
||||
}
|
||||
} break;
|
||||
case UNCOMPRESSED_R5G5B5A1:
|
||||
{
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a = 1;
|
||||
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*31/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*31/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*31/255));
|
||||
a = (pixels[k].a > 50) ? 1 : 0;
|
||||
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1| (unsigned short)a;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R4G4B4A4:
|
||||
{
|
||||
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
|
||||
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
|
||||
for (int i = 0; i < image->width*image->height; i++)
|
||||
{
|
||||
r = (unsigned char)(round((float)pixels[k].r*15/255));
|
||||
g = (unsigned char)(round((float)pixels[k].g*15/255));
|
||||
b = (unsigned char)(round((float)pixels[k].b*15/255));
|
||||
a = (unsigned char)(round((float)pixels[k].a*15/255));
|
||||
|
||||
((unsigned short *)image->data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a;
|
||||
|
||||
k++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case UNCOMPRESSED_R8G8B8A8:
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*4*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image->width*image->height*4; i += 4)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = pixels[k].r;
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].g;
|
||||
((unsigned char *)image->data)[i + 2] = pixels[k].b;
|
||||
((unsigned char *)image->data)[i + 3] = pixels[k].a;
|
||||
k++;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
free(pixels);
|
||||
}
|
||||
else TraceLog(WARNING, "Image data format is compressed, can not be converted");
|
||||
}
|
||||
|
||||
|
||||
// Convert image to POT (power-of-two)
|
||||
// NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5)
|
||||
void ImageConvertToPOT(Image *image, Color fillColor)
|
||||
{
|
||||
// TODO: Review for new image struct
|
||||
/*
|
||||
// Just add the required amount of pixels at the right and bottom sides of image...
|
||||
int potWidth = GetNextPOT(image->width);
|
||||
int potHeight = GetNextPOT(image->height);
|
||||
|
||||
// Check if POT texture generation is required (if texture is not already POT)
|
||||
if ((potWidth != image->width) || (potHeight != image->height))
|
||||
{
|
||||
Color *imgDataPixelPOT = NULL;
|
||||
|
||||
// Generate POT array from NPOT data
|
||||
imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
|
||||
|
||||
for (int j = 0; j < potHeight; j++)
|
||||
{
|
||||
for (int i = 0; i < potWidth; i++)
|
||||
{
|
||||
if ((j < image->height) && (i < image->width)) imgDataPixelPOT[j*potWidth + i] = image->data[j*image->width + i];
|
||||
else imgDataPixelPOT[j*potWidth + i] = fillColor;
|
||||
}
|
||||
}
|
||||
|
||||
TraceLog(WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight);
|
||||
|
||||
free(image->pixels);
|
||||
|
||||
image->pixels = imgDataPixelPOT;
|
||||
image->width = potWidth;
|
||||
image->height = potHeight;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Copy an image to a new image
|
||||
Image ImageCopy(Image image)
|
||||
{
|
||||
Image newImage;
|
||||
|
||||
int size = image.width*image.height;
|
||||
|
||||
switch (image.format)
|
||||
{
|
||||
case UNCOMPRESSED_GRAYSCALE: newImage.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha)
|
||||
case UNCOMPRESSED_GRAY_ALPHA: newImage.data = (unsigned char *)malloc(size*2); size *= 2; break; // 16 bpp (2 channels)
|
||||
case UNCOMPRESSED_R5G6B5: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp
|
||||
case UNCOMPRESSED_R8G8B8: newImage.data = (unsigned char *)malloc(size*3); size *= 3; break; // 24 bpp
|
||||
case UNCOMPRESSED_R5G5B5A1: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp (1 bit alpha)
|
||||
case UNCOMPRESSED_R4G4B4A4: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp (4 bit alpha)
|
||||
case UNCOMPRESSED_R8G8B8A8: newImage.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp
|
||||
default: TraceLog(WARNING, "Image format not suported for copy"); break;
|
||||
}
|
||||
|
||||
if (newImage.data != NULL)
|
||||
{
|
||||
// NOTE: Size must be provided in bytes
|
||||
memcpy(newImage.data, image.data, size);
|
||||
|
||||
newImage.width = image.width;
|
||||
newImage.height = image.height;
|
||||
newImage.mipmaps = image.mipmaps;
|
||||
newImage.format = image.format;
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
// TODO: Some useful functions to deal with images
|
||||
//void ImageCrop(Image *image, Rectangle crop) {}
|
||||
//void ImageResize(Image *image, int newWidth, int newHeight) {}
|
||||
//void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) {}
|
||||
//void ImageDrawText(Image *dst, const char *text, Vector2 position, int size, Color color) {}
|
||||
|
||||
// Generate GPU mipmaps for a texture
|
||||
void GenTextureMipmaps(Texture2D texture)
|
||||
{
|
||||
rlglGenerateMipmaps(texture.id);
|
||||
}
|
||||
|
||||
// Draw a Texture2D
|
||||
void DrawTexture(Texture2D texture, int posX, int posY, Color tint)
|
||||
{
|
||||
@ -1224,6 +1362,8 @@ static Image LoadASTC(const char *fileName)
|
||||
// NOTE: Assuming Little Endian (could it be wrong?)
|
||||
image.width = 0x00000000 | ((int)header.width[2] << 16) | ((int)header.width[1] << 8) | ((int)header.width[0]);
|
||||
image.height = 0x00000000 | ((int)header.height[2] << 16) | ((int)header.height[1] << 8) | ((int)header.height[0]);
|
||||
|
||||
// NOTE: ASTC format only contains one mipmap level
|
||||
image.mipmaps = 1;
|
||||
|
||||
TraceLog(DEBUG, "ASTC image width: %i", image.width);
|
||||
@ -1251,4 +1391,4 @@ static Image LoadASTC(const char *fileName)
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
@ -13,18 +13,23 @@
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="17" />
|
||||
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
|
||||
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
||||
<!--<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" android:required="true"/>-->
|
||||
<!-- We do not have Java code. Therefore android:hasCode is set to false. -->
|
||||
<application android:allowBackup="false" android:hasCode="false"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/icon"
|
||||
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" >
|
||||
<!-- Our activity is the built-in NativeActivity framework class. -->
|
||||
<activity android:name="android.app.NativeActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:screenOrientation="landscape"
|
||||
android:clearTaskOnLaunch="true" >
|
||||
<!-- android:theme="@android:style/Theme.NoTitleBar.Fullscreen" -->
|
||||
<!-- android:screenOrientation="portrait" -->
|
||||
<!-- Tell NativeActivity the name of our .so -->
|
||||
<!--<meta-data android:name="android.app.lib_name" android:value="raylib_game" /> -->
|
||||
<meta-data android:name="android.app.lib_name" android:value="@string/app_name" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
Loading…
Reference in New Issue
Block a user