Merge pull request #24 from raysan5/develop

Integrate Develop branch
This commit is contained in:
Ray 2015-07-28 17:38:37 +02:00
commit 8b3a82688e
19 changed files with 985 additions and 647 deletions

View File

@ -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
//--------------------------------------------------------------------------------------

View File

@ -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
//--------------------------------------------------------------------------------------

View File

@ -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);

View File

@ -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
//---------------------------------------------------------------------------------------

View File

@ -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

View File

@ -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
//--------------------------------------------------------------------------------------

View File

@ -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
View 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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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
//------------------------------------------------------------------------------------

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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" />