mirror of https://github.com/raysan5/raylib
Update to version 1.1.1
Check CHANGELOG for a detailed list of changes
This commit is contained in:
parent
5e2e9aa23e
commit
0b03431c95
19
CHANGELOG
19
CHANGELOG
|
@ -1,11 +1,28 @@
|
|||
changelog
|
||||
---------
|
||||
|
||||
Current Release: raylib 1.1.0 (April 2014)
|
||||
Current Release: raylib 1.1.1 (22 July 2014)
|
||||
|
||||
NOTE: Only versions marked as 'Release' are available on release folder, updates are only available as source.
|
||||
NOTE: Current Release includes all previous updates.
|
||||
|
||||
-----------------------------------------------
|
||||
Release: raylib 1.1.1 (22 July 2014)
|
||||
-----------------------------------------------
|
||||
[core] ShowLogo() - To enable raylib logo animation at startup
|
||||
[core] Corrected bug with window resizing
|
||||
[rlgl] Redefined colors arrays to use byte instead of float
|
||||
[rlgl] Removed double buffer system (no performance improvement)
|
||||
[rlgl] rlglDraw() - Reorganized buffers drawing order
|
||||
[rlgl] Corrected bug on screen resizing
|
||||
[models] DrawSphereWires() - Corrected some issues
|
||||
[models] LoadOBJ() - Redesigned to support multiple meshes
|
||||
[models] LoadCubesMap() - Loading a map as cubes (by pixel color)
|
||||
[textures] Added security check if file doesn't exist
|
||||
[text] Corrected bug on SpriteFont loading
|
||||
[examples] Corrected some 3d examples
|
||||
[test] Added cubesmap loading test
|
||||
|
||||
-----------------------------------------------
|
||||
Release: raylib 1.1.0 (19 April 2014)
|
||||
-----------------------------------------------
|
||||
|
|
|
@ -34,4 +34,4 @@ contact
|
|||
* Facebook: [http://www.facebook.com/raylibgames](http://www.facebook.com/raylibgames)
|
||||
|
||||
|
||||
[raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San"
|
||||
[raysan5]: mailto:raysan@raysanweb.com "Ramon Santamaria - Ray San"
|
||||
|
|
|
@ -88,6 +88,8 @@ I believe those are the best tools to train spartan-programmers.
|
|||
Someone could argue about debugging. raylib is a library intended for learning and I think C it's a clear enough language
|
||||
to allow writing small-mid size programs with a printf-based debugging. All raylib examples have also been written this way.
|
||||
|
||||
Since raylib v1.1, you can download a windows Installer package for easy installation and configuration. Check [raylib Webpage](http://www.raylib.com/)
|
||||
|
||||
building
|
||||
--------
|
||||
|
||||
|
@ -143,4 +145,4 @@ The following people have contributed in some way to make raylib project a reali
|
|||
- Victor Dual
|
||||
- Marc Palau
|
||||
|
||||
[raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San"
|
||||
[raysan5]: mailto:raysan@raysanweb.com "Ramon Santamaria - Ray San"
|
||||
|
|
|
@ -19,4 +19,4 @@ raylib v1.x
|
|||
|
||||
Any feature missing? Do you have a request? [Let me know!][raysan5]
|
||||
|
||||
[raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San"
|
||||
[raysan5]: mailto:raysan@raysanweb.com "Ramon Santamaria - Ray San"
|
||||
|
|
|
@ -47,7 +47,7 @@ int main()
|
|||
DrawCubeWires((Vector3){-4, 0, -2}, 3, 6, 2, MAROON);
|
||||
|
||||
DrawSphere((Vector3){-1, 0, -2}, 1, GREEN);
|
||||
DrawSphereWires((Vector3){1, 0, 2}, 2, LIME);
|
||||
DrawSphereWires((Vector3){1, 0, 2}, 2, 16, 16, LIME);
|
||||
|
||||
DrawCylinder((Vector3){4, 0, -2}, 1, 2, 3, 4, SKYBLUE);
|
||||
DrawCylinderWires((Vector3){4, 0, -2}, 1, 2, 3, 4, DARKBLUE);
|
||||
|
|
|
@ -221,16 +221,16 @@ typedef struct Camera {
|
|||
} Camera;
|
||||
|
||||
// Vertex data definning a mesh
|
||||
typedef struct {
|
||||
typedef struct VertexData {
|
||||
int vertexCount;
|
||||
float *vertices; // 3 components per vertex
|
||||
float *texcoords; // 2 components per vertex
|
||||
float *normals; // 3 components per vertex
|
||||
float *colors; // 4 components per vertex
|
||||
unsigned char *colors; // 4 components per vertex
|
||||
} VertexData;
|
||||
|
||||
// 3d Model type
|
||||
// NOTE: If using OpenGL 1.1 loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
|
||||
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
unsigned int vaoId;
|
||||
|
@ -282,6 +282,8 @@ int GetHexValue(Color color); // Returns hexadecim
|
|||
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
|
||||
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0 to 1.0
|
||||
|
||||
void ShowLogo(); // Activates raylib logo at startup
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
@ -395,6 +397,7 @@ void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale);
|
|||
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
|
||||
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
|
||||
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
||||
Model LoadCubesmap(Image cubesmap); // 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
|
||||
|
||||
|
|
Binary file not shown.
147
src/core.c
147
src/core.c
|
@ -86,6 +86,8 @@ static int currentMouseWheelY = 0; // Required to track mouse wheel var
|
|||
|
||||
static Color background = { 0, 0, 0, 0 }; // Screen background color
|
||||
|
||||
static bool showLogo = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Other Modules Functions Declaration (required by core)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -103,6 +105,7 @@ static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
|||
static void CursorEnterCallback(GLFWwindow* window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
|
||||
static void WindowSizeCallback(GLFWwindow* window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
||||
static void TakeScreenshot(); // Takes a screenshot and saves it in the same folder as executable
|
||||
static void LogoAnimation(); // Plays raylib logo appearing animation
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Window and OpenGL Context Functions
|
||||
|
@ -177,6 +180,13 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
|
|||
srand(time(NULL)); // Initialize random seed
|
||||
|
||||
ClearBackground(RAYWHITE); // Default background color for raylib games :P
|
||||
|
||||
// raylib logo appearing animation
|
||||
if (showLogo)
|
||||
{
|
||||
SetTargetFPS(60);
|
||||
LogoAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
// Close Window and Terminate Context
|
||||
|
@ -436,6 +446,12 @@ Color Fade(Color color, float alpha)
|
|||
return (Color){color.r, color.g, color.b, color.a*alpha};
|
||||
}
|
||||
|
||||
// Activates raylib logo at startup
|
||||
void ShowLogo()
|
||||
{
|
||||
showLogo = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -681,7 +697,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
|
|||
// GLFW3 Error Callback, runs on GLFW3 error
|
||||
static void ErrorCallback(int error, const char *description)
|
||||
{
|
||||
TraceLog(WARNING, "GLFW3 Error: %s", description);
|
||||
TraceLog(WARNING, "[GLFW3 Error] Code: %i Decription: %s", error, description);
|
||||
}
|
||||
|
||||
// GLFW3 Srolling Callback, runs on mouse wheel
|
||||
|
@ -721,9 +737,15 @@ static void WindowSizeCallback(GLFWwindow* window, int width, int height)
|
|||
int fbWidth, fbHeight;
|
||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
||||
|
||||
// If window is resized, graphics device is re-initialized
|
||||
// NOTE: Aspect ratio does not change, so, image can be deformed
|
||||
// If window is resized, graphics device is re-initialized (but only ortho mode)
|
||||
rlglInitGraphicsDevice(fbWidth, fbHeight);
|
||||
|
||||
// Window size must be updated to be used on 3D mode to get new aspect ratio (Begin3dMode())
|
||||
windowWidth = fbWidth;
|
||||
windowHeight = fbHeight;
|
||||
|
||||
// Background must be also re-cleared
|
||||
rlClearColor(background.r, background.g, background.b, background.a);
|
||||
}
|
||||
|
||||
// Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
|
||||
|
@ -747,4 +769,123 @@ static void TakeScreenshot()
|
|||
shotNum++;
|
||||
|
||||
TraceLog(INFO, "[%s] Screenshot taken!", buffer);
|
||||
}
|
||||
|
||||
static void LogoAnimation()
|
||||
{
|
||||
int logoPositionX = windowWidth/2 - 128;
|
||||
int logoPositionY = windowHeight/2 - 128;
|
||||
|
||||
int framesCounter = 0;
|
||||
int lettersCount = 0;
|
||||
|
||||
int topSideRecWidth = 16;
|
||||
int leftSideRecHeight = 16;
|
||||
|
||||
int bottomSideRecWidth = 16;
|
||||
int rightSideRecHeight = 16;
|
||||
|
||||
char raylib[8] = " "; // raylib text array, max 8 letters
|
||||
int state = 0; // Tracking animation states (State Machine)
|
||||
float alpha = 1.0; // Useful for fading
|
||||
|
||||
while (!WindowShouldClose() && (state != 4)) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0) // State 0: Small box blinking
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter == 84)
|
||||
{
|
||||
state = 1;
|
||||
framesCounter = 0; // Reset counter... will be used later...
|
||||
}
|
||||
}
|
||||
else if (state == 1) // State 1: Top and left bars growing
|
||||
{
|
||||
topSideRecWidth += 4;
|
||||
leftSideRecHeight += 4;
|
||||
|
||||
if (topSideRecWidth == 256) state = 2;
|
||||
}
|
||||
else if (state == 2) // State 2: Bottom and right bars growing
|
||||
{
|
||||
bottomSideRecWidth += 4;
|
||||
rightSideRecHeight += 4;
|
||||
|
||||
if (bottomSideRecWidth == 256) state = 3;
|
||||
}
|
||||
else if (state == 3) // State 3: Letters appearing (one by one)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter/12) // Every 12 frames, one more letter!
|
||||
{
|
||||
lettersCount++;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
switch (lettersCount)
|
||||
{
|
||||
case 1: raylib[0] = 'r'; break;
|
||||
case 2: raylib[1] = 'a'; break;
|
||||
case 3: raylib[2] = 'y'; break;
|
||||
case 4: raylib[3] = 'l'; break;
|
||||
case 5: raylib[4] = 'i'; break;
|
||||
case 6: raylib[5] = 'b'; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (lettersCount >= 10) // When all letters have appeared, just fade out everything
|
||||
{
|
||||
alpha -= 0.02;
|
||||
|
||||
if (alpha <= 0)
|
||||
{
|
||||
alpha = 0;
|
||||
state = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
if ((framesCounter/12)%2) DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK);
|
||||
}
|
||||
else if (state == 1)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK);
|
||||
}
|
||||
else if (state == 2)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK);
|
||||
|
||||
DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK);
|
||||
}
|
||||
else if (state == 3)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha));
|
||||
DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha));
|
||||
|
||||
DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha));
|
||||
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha));
|
||||
|
||||
DrawRectangle(windowWidth/2 - 112, windowHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
|
||||
|
||||
DrawText(raylib, 356, 273, 50, Fade(BLACK, alpha));
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
593
src/models.c
593
src/models.c
|
@ -681,6 +681,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
|||
vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float));
|
||||
vData.colors = (unsigned char *)malloc(vData.vertexCount * 4 * sizeof(unsigned char));
|
||||
|
||||
int vCounter = 0; // Used to count vertices float by float
|
||||
int tcCounter = 0; // Used to count texcoords float by float
|
||||
|
@ -765,6 +766,9 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
|||
|
||||
// NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct
|
||||
|
||||
// Fill color data
|
||||
for (int i = 0; i < (4*vData.vertexCount); i++) vData.colors[i] = 255;
|
||||
|
||||
Model model;
|
||||
|
||||
model.mesh = vData; // Model mesh is vertex data
|
||||
|
@ -783,6 +787,329 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
|||
return model;
|
||||
}
|
||||
|
||||
// Load a map image as a 3d model (cubes based)
|
||||
Model LoadCubesmap(Image cubesmap)
|
||||
{
|
||||
VertexData vData;
|
||||
|
||||
// Map cube size will be 1.0
|
||||
float mapCubeSide = 1.0f;
|
||||
int mapWidth = cubesmap.width * (int)mapCubeSide;
|
||||
int mapHeight = cubesmap.height * (int)mapCubeSide;
|
||||
|
||||
// NOTE: Max possible number of triangles numCubes * (12 triangles by cube)
|
||||
int maxTriangles = cubesmap.width*cubesmap.height*12;
|
||||
|
||||
int vCounter = 0; // Used to count vertices
|
||||
int tcCounter = 0; // Used to count texcoords
|
||||
int nCounter = 0; // Used to count normals
|
||||
|
||||
float w = mapCubeSide;
|
||||
float h = mapCubeSide;
|
||||
float h2 = mapCubeSide;
|
||||
|
||||
Vector3 *mapVertices = (Vector3 *)malloc(maxTriangles * 3 * sizeof(Vector3));
|
||||
Vector2 *mapTexcoords = (Vector2 *)malloc(maxTriangles * 3 * sizeof(Vector2));
|
||||
Vector3 *mapNormals = (Vector3 *)malloc(maxTriangles * 3 * sizeof(Vector3));
|
||||
|
||||
for (int z = 0; z < mapHeight; z += mapCubeSide)
|
||||
{
|
||||
for (int x = 0; x < mapWidth; x += mapCubeSide)
|
||||
{
|
||||
// Define the 8 vertex of the cube, we will combine them accordingly later...
|
||||
Vector3 v1 = { x - w/2, h2, z - h/2 };
|
||||
Vector3 v2 = { x - w/2, h2, z + h/2 };
|
||||
Vector3 v3 = { x + w/2, h2, z + h/2 };
|
||||
Vector3 v4 = { x + w/2, h2, z - h/2 };
|
||||
Vector3 v5 = { x + w/2, 0, z - h/2 };
|
||||
Vector3 v6 = { x - w/2, 0, z - h/2 };
|
||||
Vector3 v7 = { x - w/2, 0, z + h/2 };
|
||||
Vector3 v8 = { x + w/2, 0, z + h/2 };
|
||||
|
||||
// Define the 6 normals of the cube, we will combine them accordingly later...
|
||||
Vector3 n1 = { 1.0f, 0.0f, 0.0f };
|
||||
Vector3 n2 = { -1.0f, 0.0f, 0.0f };
|
||||
Vector3 n3 = { 0.0f, 1.0f, 0.0f };
|
||||
Vector3 n4 = { 0.0f, -1.0f, 0.0f };
|
||||
Vector3 n5 = { 0.0f, 0.0f, 1.0f };
|
||||
Vector3 n6 = { 0.0f, 0.0f, -1.0f };
|
||||
|
||||
// Define the 4 texture coordinates of the cube, we will combine them accordingly later...
|
||||
// TODO: Use texture rectangles to define different textures for top-bottom-front-back-right-left (6)
|
||||
Vector2 vt2 = { 0.0f, 0.0f };
|
||||
Vector2 vt1 = { 0.0f, 1.0f };
|
||||
Vector2 vt4 = { 1.0f, 0.0f };
|
||||
Vector2 vt3 = { 1.0f, 1.0f };
|
||||
|
||||
// We check pixel color to be WHITE, we will full cubes
|
||||
if ((cubesmap.pixels[z*cubesmap.width + x].r == 255) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + x].g == 255) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + x].b == 255))
|
||||
{
|
||||
// Define triangles (Checking Collateral Cubes!)
|
||||
//----------------------------------------------
|
||||
|
||||
// Define top triangles (2 tris, 6 vertex --> v1-v2-v3, v1-v3-v4)
|
||||
mapVertices[vCounter] = v1;
|
||||
mapVertices[vCounter + 1] = v2;
|
||||
mapVertices[vCounter + 2] = v3;
|
||||
mapVertices[vCounter + 3] = v1;
|
||||
mapVertices[vCounter + 4] = v3;
|
||||
mapVertices[vCounter + 5] = v4;
|
||||
vCounter += 6;
|
||||
|
||||
mapNormals[nCounter] = n3;
|
||||
mapNormals[nCounter + 1] = n3;
|
||||
mapNormals[nCounter + 2] = n3;
|
||||
mapNormals[nCounter + 3] = n3;
|
||||
mapNormals[nCounter + 4] = n3;
|
||||
mapNormals[nCounter + 5] = n3;
|
||||
nCounter += 6;
|
||||
|
||||
mapTexcoords[tcCounter] = vt2;
|
||||
mapTexcoords[tcCounter + 1] = vt1;
|
||||
mapTexcoords[tcCounter + 2] = vt3;
|
||||
mapTexcoords[tcCounter + 3] = vt2;
|
||||
mapTexcoords[tcCounter + 4] = vt3;
|
||||
mapTexcoords[tcCounter + 5] = vt4;
|
||||
tcCounter += 6;
|
||||
|
||||
// Define bottom triangles (2 tris, 6 vertex --> v6-v8-v7, v6-v5-v8)
|
||||
mapVertices[vCounter] = v6;
|
||||
mapVertices[vCounter + 1] = v8;
|
||||
mapVertices[vCounter + 2] = v7;
|
||||
mapVertices[vCounter + 3] = v6;
|
||||
mapVertices[vCounter + 4] = v5;
|
||||
mapVertices[vCounter + 5] = v8;
|
||||
vCounter += 6;
|
||||
|
||||
mapNormals[nCounter] = n4;
|
||||
mapNormals[nCounter + 1] = n4;
|
||||
mapNormals[nCounter + 2] = n4;
|
||||
mapNormals[nCounter + 3] = n4;
|
||||
mapNormals[nCounter + 4] = n4;
|
||||
mapNormals[nCounter + 5] = n4;
|
||||
nCounter += 6;
|
||||
|
||||
mapTexcoords[tcCounter] = vt4;
|
||||
mapTexcoords[tcCounter + 1] = vt1;
|
||||
mapTexcoords[tcCounter + 2] = vt3;
|
||||
mapTexcoords[tcCounter + 3] = vt4;
|
||||
mapTexcoords[tcCounter + 4] = vt2;
|
||||
mapTexcoords[tcCounter + 5] = vt1;
|
||||
tcCounter += 6;
|
||||
|
||||
if (((z < cubesmap.height - 1) &&
|
||||
(cubesmap.pixels[(z + 1)*cubesmap.width + x].r == 0) &&
|
||||
(cubesmap.pixels[(z + 1)*cubesmap.width + x].g == 0) &&
|
||||
(cubesmap.pixels[(z + 1)*cubesmap.width + x].b == 0)) || (z == cubesmap.height - 1))
|
||||
{
|
||||
// Define front triangles (2 tris, 6 vertex) --> v2 v7 v3, v3 v7 v8
|
||||
// NOTE: Collateral occluded faces are not generated
|
||||
mapVertices[vCounter] = v2;
|
||||
mapVertices[vCounter + 1] = v7;
|
||||
mapVertices[vCounter + 2] = v3;
|
||||
mapVertices[vCounter + 3] = v3;
|
||||
mapVertices[vCounter + 4] = v7;
|
||||
mapVertices[vCounter + 5] = v8;
|
||||
vCounter += 6;
|
||||
|
||||
mapNormals[nCounter] = n6;
|
||||
mapNormals[nCounter + 1] = n6;
|
||||
mapNormals[nCounter + 2] = n6;
|
||||
mapNormals[nCounter + 3] = n6;
|
||||
mapNormals[nCounter + 4] = n6;
|
||||
mapNormals[nCounter + 5] = n6;
|
||||
nCounter += 6;
|
||||
|
||||
mapTexcoords[tcCounter] = vt2;
|
||||
mapTexcoords[tcCounter + 1] = vt1;
|
||||
mapTexcoords[tcCounter + 2] = vt4;
|
||||
mapTexcoords[tcCounter + 3] = vt4;
|
||||
mapTexcoords[tcCounter + 4] = vt1;
|
||||
mapTexcoords[tcCounter + 5] = vt3;
|
||||
tcCounter += 6;
|
||||
}
|
||||
|
||||
if (((z > 0) &&
|
||||
(cubesmap.pixels[(z - 1)*cubesmap.width + x].r == 0) &&
|
||||
(cubesmap.pixels[(z - 1)*cubesmap.width + x].g == 0) &&
|
||||
(cubesmap.pixels[(z - 1)*cubesmap.width + x].b == 0)) || (z == 0))
|
||||
{
|
||||
// Define back triangles (2 tris, 6 vertex) --> v1 v5 v6, v1 v4 v5
|
||||
// NOTE: Collateral occluded faces are not generated
|
||||
mapVertices[vCounter] = v1;
|
||||
mapVertices[vCounter + 1] = v5;
|
||||
mapVertices[vCounter + 2] = v6;
|
||||
mapVertices[vCounter + 3] = v1;
|
||||
mapVertices[vCounter + 4] = v4;
|
||||
mapVertices[vCounter + 5] = v5;
|
||||
vCounter += 6;
|
||||
|
||||
mapNormals[nCounter] = n5;
|
||||
mapNormals[nCounter + 1] = n5;
|
||||
mapNormals[nCounter + 2] = n5;
|
||||
mapNormals[nCounter + 3] = n5;
|
||||
mapNormals[nCounter + 4] = n5;
|
||||
mapNormals[nCounter + 5] = n5;
|
||||
nCounter += 6;
|
||||
|
||||
mapTexcoords[tcCounter] = vt4;
|
||||
mapTexcoords[tcCounter + 1] = vt1;
|
||||
mapTexcoords[tcCounter + 2] = vt3;
|
||||
mapTexcoords[tcCounter + 3] = vt4;
|
||||
mapTexcoords[tcCounter + 4] = vt2;
|
||||
mapTexcoords[tcCounter + 5] = vt1;
|
||||
tcCounter += 6;
|
||||
}
|
||||
|
||||
if (((x < cubesmap.width - 1) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + (x + 1)].r == 0) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + (x + 1)].g == 0) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + (x + 1)].b == 0)) || (x == cubesmap.width - 1))
|
||||
{
|
||||
// Define right triangles (2 tris, 6 vertex) --> v3 v8 v4, v4 v8 v5
|
||||
// NOTE: Collateral occluded faces are not generated
|
||||
mapVertices[vCounter] = v3;
|
||||
mapVertices[vCounter + 1] = v8;
|
||||
mapVertices[vCounter + 2] = v4;
|
||||
mapVertices[vCounter + 3] = v4;
|
||||
mapVertices[vCounter + 4] = v8;
|
||||
mapVertices[vCounter + 5] = v5;
|
||||
vCounter += 6;
|
||||
|
||||
mapNormals[nCounter] = n1;
|
||||
mapNormals[nCounter + 1] = n1;
|
||||
mapNormals[nCounter + 2] = n1;
|
||||
mapNormals[nCounter + 3] = n1;
|
||||
mapNormals[nCounter + 4] = n1;
|
||||
mapNormals[nCounter + 5] = n1;
|
||||
nCounter += 6;
|
||||
|
||||
mapTexcoords[tcCounter] = vt2;
|
||||
mapTexcoords[tcCounter + 1] = vt1;
|
||||
mapTexcoords[tcCounter + 2] = vt4;
|
||||
mapTexcoords[tcCounter + 3] = vt4;
|
||||
mapTexcoords[tcCounter + 4] = vt1;
|
||||
mapTexcoords[tcCounter + 5] = vt3;
|
||||
tcCounter += 6;
|
||||
}
|
||||
|
||||
if (((x > 0) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + (x - 1)].r == 0) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + (x - 1)].g == 0) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + (x - 1)].b == 0)) || (x == 0))
|
||||
{
|
||||
// Define left triangles (2 tris, 6 vertex) --> v1 v7 v2, v1 v6 v7
|
||||
// NOTE: Collateral occluded faces are not generated
|
||||
mapVertices[vCounter] = v1;
|
||||
mapVertices[vCounter + 1] = v7;
|
||||
mapVertices[vCounter + 2] = v2;
|
||||
mapVertices[vCounter + 3] = v1;
|
||||
mapVertices[vCounter + 4] = v6;
|
||||
mapVertices[vCounter + 5] = v7;
|
||||
vCounter += 6;
|
||||
|
||||
mapNormals[nCounter] = n2;
|
||||
mapNormals[nCounter + 1] = n2;
|
||||
mapNormals[nCounter + 2] = n2;
|
||||
mapNormals[nCounter + 3] = n2;
|
||||
mapNormals[nCounter + 4] = n2;
|
||||
mapNormals[nCounter + 5] = n2;
|
||||
nCounter += 6;
|
||||
|
||||
mapTexcoords[tcCounter] = vt2;
|
||||
mapTexcoords[tcCounter + 1] = vt3;
|
||||
mapTexcoords[tcCounter + 2] = vt4;
|
||||
mapTexcoords[tcCounter + 3] = vt2;
|
||||
mapTexcoords[tcCounter + 4] = vt1;
|
||||
mapTexcoords[tcCounter + 5] = vt3;
|
||||
tcCounter += 6;
|
||||
}
|
||||
}
|
||||
// We check pixel color to be BLACK, we will only draw floor and roof
|
||||
else if ((cubesmap.pixels[z*cubesmap.width + x].r == 0) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + x].g == 0) &&
|
||||
(cubesmap.pixels[z*cubesmap.width + x].b == 0))
|
||||
{
|
||||
// Define top triangles (2 tris, 6 vertex --> v1-v3-v2, v1-v4-v3)
|
||||
// TODO: ...
|
||||
|
||||
// Define bottom triangles (2 tris, 6 vertex --> v6-v7-v8, v6-v8-v5)
|
||||
// TODO: ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move data from mapVertices temp arays to vertices float array
|
||||
vData.vertexCount = vCounter;
|
||||
|
||||
printf("Vertex count: %i\n", vCounter);
|
||||
|
||||
vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float));
|
||||
vData.colors = (unsigned char *)malloc(vData.vertexCount * 4 * sizeof(unsigned char));
|
||||
|
||||
// Fill color data
|
||||
for (int i = 0; i < (4*vData.vertexCount); i++) vData.colors[i] = 255;
|
||||
|
||||
int fCounter = 0;
|
||||
|
||||
// Move vertices data
|
||||
for (int i = 0; i < vCounter; i++)
|
||||
{
|
||||
vData.vertices[fCounter] = mapVertices[i].x;
|
||||
vData.vertices[fCounter + 1] = mapVertices[i].y;
|
||||
vData.vertices[fCounter + 2] = mapVertices[i].z;
|
||||
fCounter += 3;
|
||||
}
|
||||
|
||||
fCounter = 0;
|
||||
|
||||
// Move normals data
|
||||
for (int i = 0; i < nCounter; i++)
|
||||
{
|
||||
vData.normals[fCounter] = mapNormals[i].x;
|
||||
vData.normals[fCounter + 1] = mapNormals[i].y;
|
||||
vData.normals[fCounter + 2] = mapNormals[i].z;
|
||||
fCounter += 3;
|
||||
}
|
||||
|
||||
fCounter = 0;
|
||||
|
||||
// Move texcoords data
|
||||
for (int i = 0; i < tcCounter; i++)
|
||||
{
|
||||
vData.texcoords[fCounter] = mapTexcoords[i].x;
|
||||
vData.texcoords[fCounter + 1] = mapTexcoords[i].y;
|
||||
fCounter += 2;
|
||||
}
|
||||
|
||||
free(mapVertices);
|
||||
free(mapNormals);
|
||||
free(mapTexcoords);
|
||||
|
||||
// NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct
|
||||
|
||||
Model model;
|
||||
|
||||
model.mesh = vData; // Model mesh is vertex data
|
||||
model.textureId = 0;
|
||||
|
||||
#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
|
||||
model.vaoId = rlglLoadModel(vData); // Use loaded data to generate VAO
|
||||
model.textureId = 1; // Default whiteTexture
|
||||
|
||||
// Now that vertex data is uploaded to GPU, we can free arrays
|
||||
//free(vData.vertices);
|
||||
//free(vData.texcoords);
|
||||
//free(vData.normals);
|
||||
#endif
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
// Unload 3d model from memory
|
||||
void UnloadModel(Model model)
|
||||
{
|
||||
|
@ -945,141 +1272,81 @@ static VertexData LoadOBJ(const char *fileName)
|
|||
|
||||
objFile = fopen(fileName, "rt");
|
||||
|
||||
// First pass over all file to get numVertex, numNormals, numTexCoords, numTriangles
|
||||
// First reading pass: Get numVertex, numNormals, numTexCoords, numTriangles
|
||||
// NOTE: vertex, texcoords and normals could be optimized (to be used indexed on faces definition)
|
||||
// NOTE: faces MUST be defined as TRIANGLES, not QUADS
|
||||
while(!feof(objFile))
|
||||
{
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
||||
switch(dataType)
|
||||
{
|
||||
case '#': // It's a comment
|
||||
case '#': // Comments
|
||||
case 'o': // Object name (One OBJ file can contain multible named meshes)
|
||||
case 'g': // Group name
|
||||
case 's': // Smoothing level
|
||||
case 'm': // mtllib [external .mtl file name]
|
||||
case 'u': // usemtl [material name]
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
} break;
|
||||
case 'o': // New object
|
||||
{
|
||||
// TODO: Read multiple objects, we need to know numMeshes + verticesPerMesh
|
||||
|
||||
// NOTE: One OBJ file can contain multible meshes defined, one after every 'o'
|
||||
|
||||
} break;
|
||||
fgets(comments, 200, objFile);
|
||||
} break;
|
||||
case 'v':
|
||||
{
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
||||
if (dataType == 't') // Read texCoord
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
||||
while (dataType == 'v')
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
}
|
||||
|
||||
if (dataType == '#')
|
||||
{
|
||||
fscanf(objFile, "%i", &numTexCoords);
|
||||
}
|
||||
|
||||
numTexCoords++;
|
||||
fgets(comments, 200, objFile);
|
||||
}
|
||||
else if (dataType == 'n') // Read normals
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
||||
while (dataType == 'v')
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
}
|
||||
|
||||
if (dataType == '#')
|
||||
{
|
||||
fscanf(objFile, "%i", &numNormals);
|
||||
}
|
||||
|
||||
numNormals++;
|
||||
fgets(comments, 200, objFile);
|
||||
}
|
||||
else // Read vertex
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
||||
while (dataType == 'v')
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
}
|
||||
|
||||
if (dataType == '#')
|
||||
{
|
||||
fscanf(objFile, "%i", &numVertex);
|
||||
}
|
||||
|
||||
numVertex++;
|
||||
fgets(comments, 200, objFile);
|
||||
}
|
||||
} break;
|
||||
case 'f':
|
||||
{
|
||||
numTriangles++;
|
||||
fgets(comments, 200, objFile);
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
||||
while (dataType == 'f')
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
}
|
||||
|
||||
if (dataType == '#')
|
||||
{
|
||||
fscanf(objFile, "%i", &numTriangles);
|
||||
}
|
||||
|
||||
fgets(comments, 200, objFile);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
TraceLog(DEBUG, "[%s] Model num vertices: %i", fileName, numVertex);
|
||||
TraceLog(DEBUG, "[%s] Model num texcoords: %i", fileName, numTexCoords);
|
||||
TraceLog(DEBUG, "[%s] Model num normals: %i", fileName, numNormals);
|
||||
TraceLog(DEBUG, "[%s] Model num triangles: %i", fileName, numTriangles);
|
||||
|
||||
// Once we know the number of vertices to store, we create required arrays
|
||||
Vector3 *midVertices = (Vector3 *)malloc(numVertex*sizeof(Vector3));
|
||||
Vector3 *midNormals = (Vector3 *)malloc(numNormals*sizeof(Vector3));
|
||||
Vector2 *midTexCoords = (Vector2 *)malloc(numTexCoords*sizeof(Vector2));
|
||||
|
||||
vData.vertexCount = numTriangles*3;
|
||||
|
||||
// Additional arrays to store vertex data as floats
|
||||
vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float));
|
||||
vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.colors = (float *)malloc(vData.vertexCount * 4 * sizeof(float));
|
||||
|
||||
Vector3 *midNormals;
|
||||
if (numNormals > 0) midNormals = (Vector3 *)malloc(numNormals*sizeof(Vector3));
|
||||
Vector2 *midTexCoords;
|
||||
if (numTexCoords > 0) midTexCoords = (Vector2 *)malloc(numTexCoords*sizeof(Vector2));
|
||||
|
||||
int countVertex = 0;
|
||||
int countNormals = 0;
|
||||
int countTexCoords = 0;
|
||||
|
||||
int vCounter = 0; // Used to count vertices float by float
|
||||
int tcCounter = 0; // Used to count texcoords float by float
|
||||
int nCounter = 0; // Used to count normals float by float
|
||||
|
||||
|
||||
rewind(objFile); // Return to the beginning of the file, to read again
|
||||
|
||||
// Reading again file to get vertex data
|
||||
// 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)
|
||||
while(!feof(objFile))
|
||||
{
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
||||
switch(dataType)
|
||||
{
|
||||
case '#':
|
||||
{
|
||||
fgets(comments, 200, objFile);
|
||||
} break;
|
||||
case '#': case 'o': case 'g': case 's': case 'm': case 'u': case 'f': fgets(comments, 200, objFile); break;
|
||||
case 'v':
|
||||
{
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
@ -1108,60 +1375,107 @@ static VertexData LoadOBJ(const char *fileName)
|
|||
fscanf(objFile, "%c", &dataType);
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point all vertex data (v, vt, vn) has been gathered on midVertices, midTexCoords, midNormals
|
||||
// Now we can organize that data into our VertexData struct
|
||||
|
||||
vData.vertexCount = numTriangles*3;
|
||||
|
||||
// Additional arrays to store vertex data as floats
|
||||
vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float));
|
||||
vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.colors = (unsigned char *)malloc(vData.vertexCount * 4 * sizeof(unsigned char));
|
||||
|
||||
int vCounter = 0; // Used to count vertices float by float
|
||||
int tcCounter = 0; // Used to count texcoords float by float
|
||||
int nCounter = 0; // Used to count normals float by float
|
||||
|
||||
int vNum[3], vtNum[3], vnNum[3];
|
||||
|
||||
rewind(objFile); // Return to the beginning of the file, to read again
|
||||
|
||||
if (numNormals == 0) TraceLog(INFO, "[%s] No normals data on OBJ, normals will be generated from faces data", fileName);
|
||||
|
||||
// Third reading pass: Get faces (triangles) data and fill VertexArray
|
||||
while(!feof(objFile))
|
||||
{
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
|
||||
switch(dataType)
|
||||
{
|
||||
case '#': case 'o': case 'g': case 's': case 'm': case 'u': case 'v': fgets(comments, 200, objFile); break;
|
||||
case 'f':
|
||||
{
|
||||
// At this point all vertex data (v, vt, vn) have been gathered on midVertices, midTexCoords, midNormals
|
||||
// Now we can organize that data into our VertexData struct
|
||||
|
||||
int vNum, vtNum, vnNum;
|
||||
fscanf(objFile, "%c", &dataType);
|
||||
fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
|
||||
// NOTE: It could be that OBJ does not have normals or texcoords defined!
|
||||
|
||||
vData.vertices[vCounter] = midVertices[vNum-1].x;
|
||||
vData.vertices[vCounter + 1] = midVertices[vNum-1].y;
|
||||
vData.vertices[vCounter + 2] = midVertices[vNum-1].z;
|
||||
if ((numNormals == 0) && (numTexCoords == 0)) fscanf(objFile, "%i %i %i", &vNum[0], &vNum[1], &vNum[2]);
|
||||
else if (numNormals == 0) fscanf(objFile, "%i/%i %i/%i %i/%i", &vNum[0], &vtNum[0], &vNum[1], &vtNum[1], &vNum[2], &vtNum[2]);
|
||||
else fscanf(objFile, "%i/%i/%i %i/%i/%i %i/%i/%i", &vNum[0], &vtNum[0], &vnNum[0], &vNum[1], &vtNum[1], &vnNum[1], &vNum[2], &vtNum[2], &vnNum[2]);
|
||||
|
||||
vData.vertices[vCounter] = midVertices[vNum[0]-1].x;
|
||||
vData.vertices[vCounter + 1] = midVertices[vNum[0]-1].y;
|
||||
vData.vertices[vCounter + 2] = midVertices[vNum[0]-1].z;
|
||||
vCounter += 3;
|
||||
vData.vertices[vCounter] = midVertices[vNum[1]-1].x;
|
||||
vData.vertices[vCounter + 1] = midVertices[vNum[1]-1].y;
|
||||
vData.vertices[vCounter + 2] = midVertices[vNum[1]-1].z;
|
||||
vCounter += 3;
|
||||
vData.vertices[vCounter] = midVertices[vNum[2]-1].x;
|
||||
vData.vertices[vCounter + 1] = midVertices[vNum[2]-1].y;
|
||||
vData.vertices[vCounter + 2] = midVertices[vNum[2]-1].z;
|
||||
vCounter += 3;
|
||||
|
||||
vData.normals[nCounter] = midNormals[vnNum-1].x;
|
||||
vData.normals[nCounter + 1] = midNormals[vnNum-1].y;
|
||||
vData.normals[nCounter + 2] = midNormals[vnNum-1].z;
|
||||
nCounter += 3;
|
||||
if (numNormals > 0)
|
||||
{
|
||||
vData.normals[nCounter] = midNormals[vnNum[0]-1].x;
|
||||
vData.normals[nCounter + 1] = midNormals[vnNum[0]-1].y;
|
||||
vData.normals[nCounter + 2] = midNormals[vnNum[0]-1].z;
|
||||
nCounter += 3;
|
||||
vData.normals[nCounter] = midNormals[vnNum[1]-1].x;
|
||||
vData.normals[nCounter + 1] = midNormals[vnNum[1]-1].y;
|
||||
vData.normals[nCounter + 2] = midNormals[vnNum[1]-1].z;
|
||||
nCounter += 3;
|
||||
vData.normals[nCounter] = midNormals[vnNum[2]-1].x;
|
||||
vData.normals[nCounter + 1] = midNormals[vnNum[2]-1].y;
|
||||
vData.normals[nCounter + 2] = midNormals[vnNum[2]-1].z;
|
||||
nCounter += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If normals not defined, they are calculated from the 3 vertices [N = (V2 - V1) x (V3 - V1)]
|
||||
Vector3 norm = VectorCrossProduct(VectorSubtract(midVertices[vNum[1]-1], midVertices[vNum[0]-1]), VectorSubtract(midVertices[vNum[2]-1], midVertices[vNum[0]-1]));
|
||||
VectorNormalize(&norm);
|
||||
|
||||
vData.normals[nCounter] = norm.x;
|
||||
vData.normals[nCounter + 1] = norm.y;
|
||||
vData.normals[nCounter + 2] = norm.z;
|
||||
nCounter += 3;
|
||||
vData.normals[nCounter] = norm.x;
|
||||
vData.normals[nCounter + 1] = norm.y;
|
||||
vData.normals[nCounter + 2] = norm.z;
|
||||
nCounter += 3;
|
||||
vData.normals[nCounter] = norm.x;
|
||||
vData.normals[nCounter + 1] = norm.y;
|
||||
vData.normals[nCounter + 2] = norm.z;
|
||||
nCounter += 3;
|
||||
}
|
||||
|
||||
vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x;
|
||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y;
|
||||
tcCounter += 2;
|
||||
|
||||
fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
|
||||
|
||||
vData.vertices[vCounter] = midVertices[vNum-1].x;
|
||||
vData.vertices[vCounter + 1] = midVertices[vNum-1].y;
|
||||
vData.vertices[vCounter + 2] = midVertices[vNum-1].z;
|
||||
vCounter += 3;
|
||||
|
||||
vData.normals[nCounter] = midNormals[vnNum-1].x;
|
||||
vData.normals[nCounter + 1] = midNormals[vnNum-1].y;
|
||||
vData.normals[nCounter + 2] = midNormals[vnNum-1].z;
|
||||
nCounter += 3;
|
||||
|
||||
vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x;
|
||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y;
|
||||
tcCounter += 2;
|
||||
|
||||
fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
|
||||
|
||||
vData.vertices[vCounter] = midVertices[vNum-1].x;
|
||||
vData.vertices[vCounter + 1] = midVertices[vNum-1].y;
|
||||
vData.vertices[vCounter + 2] = midVertices[vNum-1].z;
|
||||
vCounter += 3;
|
||||
|
||||
vData.normals[nCounter] = midNormals[vnNum-1].x;
|
||||
vData.normals[nCounter + 1] = midNormals[vnNum-1].y;
|
||||
vData.normals[nCounter + 2] = midNormals[vnNum-1].z;
|
||||
nCounter += 3;
|
||||
|
||||
vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x;
|
||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y;
|
||||
tcCounter += 2;
|
||||
if (numTexCoords > 0)
|
||||
{
|
||||
vData.texcoords[tcCounter] = midTexCoords[vtNum[0]-1].x;
|
||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum[0]-1].y;
|
||||
tcCounter += 2;
|
||||
vData.texcoords[tcCounter] = midTexCoords[vtNum[1]-1].x;
|
||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum[1]-1].y;
|
||||
tcCounter += 2;
|
||||
vData.texcoords[tcCounter] = midTexCoords[vtNum[2]-1].x;
|
||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum[2]-1].y;
|
||||
tcCounter += 2;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
@ -1169,8 +1483,11 @@ static VertexData LoadOBJ(const char *fileName)
|
|||
|
||||
fclose(objFile);
|
||||
|
||||
// Security check, just in case no normals or no texcoords defined in OBJ
|
||||
if (numTexCoords == 0) for (int i = 0; i < (2*vData.vertexCount); i++) vData.texcoords[i] = 0.0f;
|
||||
|
||||
// NOTE: We set all vertex colors to white
|
||||
for (int i = 0; i < (4*vData.vertexCount); i++) vData.colors[i] = 1.0f;
|
||||
for (int i = 0; i < (4*vData.vertexCount); i++) vData.colors[i] = 255;
|
||||
|
||||
// Now we can free temp mid* arrays
|
||||
free(midVertices);
|
||||
|
|
|
@ -226,11 +226,11 @@ typedef struct VertexData {
|
|||
float *vertices; // 3 components per vertex
|
||||
float *texcoords; // 2 components per vertex
|
||||
float *normals; // 3 components per vertex
|
||||
float *colors; // 4 components per vertex
|
||||
unsigned char *colors; // 4 components per vertex
|
||||
} VertexData;
|
||||
|
||||
// 3d Model type
|
||||
// NOTE: If using OpenGL 1.1 loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
|
||||
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
unsigned int vaoId;
|
||||
|
@ -282,6 +282,8 @@ int GetHexValue(Color color); // Returns hexadecim
|
|||
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
|
||||
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0 to 1.0
|
||||
|
||||
void ShowLogo(); // Activates raylib logo at startup
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
@ -395,6 +397,7 @@ void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale);
|
|||
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
|
||||
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
|
||||
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
||||
Model LoadCubesmap(Image cubesmap); // 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
|
||||
|
||||
|
|
260
src/rlgl.c
260
src/rlgl.c
|
@ -58,8 +58,6 @@
|
|||
|
||||
//#include "glad.h" // Other extensions loading lib? --> REVIEW
|
||||
|
||||
#define USE_VBO_DOUBLE_BUFFERS // Enable VBO double buffers usage --> REVIEW!
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -77,7 +75,7 @@ typedef struct {
|
|||
int vCounter;
|
||||
int cCounter;
|
||||
float *vertices; // 3 components per vertex
|
||||
float *colors; // 4 components per vertex
|
||||
unsigned char *colors; // 4 components per vertex
|
||||
} VertexPositionColorBuffer;
|
||||
|
||||
// Vertex buffer (position + texcoords + color arrays)
|
||||
|
@ -88,7 +86,7 @@ typedef struct {
|
|||
int cCounter;
|
||||
float *vertices; // 3 components per vertex
|
||||
float *texcoords; // 2 components per vertex
|
||||
float *colors; // 4 components per vertex
|
||||
unsigned char *colors; // 4 components per vertex
|
||||
} VertexPositionColorTextureBuffer;
|
||||
|
||||
// Vertex buffer (position + texcoords + normals arrays)
|
||||
|
@ -110,7 +108,7 @@ typedef struct {
|
|||
int cCounter;
|
||||
float *vertices; // 3 components per vertex
|
||||
float *texcoords; // 2 components per vertex
|
||||
float *colors; // 4 components per vertex
|
||||
unsigned char *colors; // 4 components per vertex
|
||||
unsigned int *indices; // 6 indices per quad
|
||||
} VertexPositionColorTextureIndexBuffer;
|
||||
|
||||
|
@ -165,13 +163,6 @@ static GLuint linesBuffer[2];
|
|||
static GLuint trianglesBuffer[2];
|
||||
static GLuint quadsBuffer[4];
|
||||
|
||||
#ifdef USE_VBO_DOUBLE_BUFFERS
|
||||
// Double buffering
|
||||
static GLuint vaoQuadsB;
|
||||
static GLuint quadsBufferB[4];
|
||||
static bool useBufferB = false;
|
||||
#endif
|
||||
|
||||
static DrawCall *draws;
|
||||
static int drawsCounter;
|
||||
|
||||
|
@ -566,7 +557,7 @@ void rlNormal3f(float x, float y, float z)
|
|||
}
|
||||
|
||||
// Define one vertex (color)
|
||||
void rlColor4f(float x, float y, float z, float w)
|
||||
void rlColor4ub(byte x, byte y, byte z, byte w)
|
||||
{
|
||||
switch (currentDrawMode)
|
||||
{
|
||||
|
@ -605,15 +596,15 @@ void rlColor4f(float x, float y, float z, float w)
|
|||
}
|
||||
|
||||
// Define one vertex (color)
|
||||
void rlColor4ub(byte r, byte g, byte b, byte a)
|
||||
void rlColor4f(float r, float g, float b, float a)
|
||||
{
|
||||
rlColor4f((float)r/255, (float)g/255, (float)b/255, (float)a/255);
|
||||
rlColor4ub((byte)(r*255), (byte)(g*255), (byte)(b*255), (byte)(a*255));
|
||||
}
|
||||
|
||||
// Define one vertex (color)
|
||||
void rlColor3f(float x, float y, float z)
|
||||
{
|
||||
rlColor4f(x, y, z, 1.0);
|
||||
rlColor4ub((byte)(x*255), (byte)(y*255), (byte)(z*255), 255);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -826,48 +817,23 @@ void rlglClose()
|
|||
|
||||
void rlglDraw()
|
||||
{
|
||||
UpdateBuffers();
|
||||
|
||||
glUseProgram(shaderProgram); // Use our shader
|
||||
|
||||
glUniformMatrix4fv(projectionMatrixLoc, 1, false, GetMatrixVector(projection));
|
||||
glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelview));
|
||||
glUniform1i(textureLoc, 0);
|
||||
|
||||
UpdateBuffers();
|
||||
|
||||
if (lines.vCounter > 0)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, whiteTexture);
|
||||
|
||||
glBindVertexArray(vaoLines);
|
||||
glDrawArrays(GL_LINES, 0, lines.vCounter);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
if (triangles.vCounter > 0)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, whiteTexture);
|
||||
|
||||
glBindVertexArray(vaoTriangles);
|
||||
glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// NOTE: We draw in this order: textured quads, triangles shapes, lines
|
||||
|
||||
if (quads.vCounter > 0)
|
||||
{
|
||||
int quadsCount = 0;
|
||||
int numIndicesToProcess = 0;
|
||||
int indicesOffset = 0;
|
||||
|
||||
#ifdef USE_VBO_DOUBLE_BUFFERS
|
||||
// Depending on useBufferB, use Buffer A or Buffer B
|
||||
if (useBufferB) glBindVertexArray(vaoQuadsB);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
glBindVertexArray(vaoQuads);
|
||||
}
|
||||
glBindVertexArray(vaoQuads);
|
||||
|
||||
//TraceLog(DEBUG, "Draws required per frame: %i", drawsCounter);
|
||||
|
||||
|
@ -885,9 +851,30 @@ void rlglDraw()
|
|||
|
||||
indicesOffset += draws[i].vertexCount/4*6;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
||||
}
|
||||
|
||||
if (triangles.vCounter > 0)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, whiteTexture);
|
||||
|
||||
glBindVertexArray(vaoTriangles);
|
||||
glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
if (lines.vCounter > 0)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, whiteTexture);
|
||||
|
||||
glBindVertexArray(vaoLines);
|
||||
glDrawArrays(GL_LINES, 0, lines.vCounter);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
||||
glBindVertexArray(0); // Unbind VAO
|
||||
|
||||
// Reset draws counter
|
||||
|
@ -905,11 +892,6 @@ void rlglDraw()
|
|||
quads.vCounter = 0;
|
||||
quads.tcCounter = 0;
|
||||
quads.cCounter = 0;
|
||||
|
||||
// TODO: Review double buffer performance -> no improvement! (?)
|
||||
#ifdef USE_VBO_DOUBLE_BUFFERS
|
||||
useBufferB = !useBufferB; // Change buffers usage!
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // End for OpenGL 3.3+ and ES2 only functions
|
||||
|
@ -931,7 +913,7 @@ void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scal
|
|||
glVertexPointer(3, GL_FLOAT, 0, model.mesh.vertices); // Pointer to vertex coords array
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, model.mesh.texcoords); // Pointer to texture coords array
|
||||
glNormalPointer(GL_FLOAT, 0, model.mesh.normals); // Pointer to normals array
|
||||
//glColorPointer(4, GL_UNSIGNED_BYTE, 0, model.colors); // Pointer to colors array (NOT USED)
|
||||
//glColorPointer(4, GL_UNSIGNED_BYTE, 0, model.mesh.colors); // Pointer to colors array (NOT USED)
|
||||
|
||||
//TraceLog(DEBUG, "Drawing model.mesh, VertexCount: %i", model.mesh.vertexCount);
|
||||
|
||||
|
@ -966,15 +948,36 @@ void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scal
|
|||
glUniformMatrix4fv(projectionMatrixLoc, 1, false, GetMatrixVector(projection));
|
||||
glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelviewworld));
|
||||
glUniform1i(textureLoc, 0);
|
||||
|
||||
// Apply color tinting to model: 2 OPTIONS
|
||||
/*
|
||||
// OPTION 1
|
||||
// Update colors array (model.mesh.colors) with color
|
||||
int j = 0;
|
||||
for (int i = 0; i < model.mesh.vertexCount; i++)
|
||||
{
|
||||
model.mesh.colors[j] = color.r;
|
||||
model.mesh.colors[j+1] = color.g;
|
||||
model.mesh.colors[j+2] = color.b;
|
||||
model.mesh.colors[j+3] = color.a;
|
||||
j += 4;
|
||||
}
|
||||
|
||||
// Update colors buffer in CPU (using Shader)
|
||||
glBindVertexArray(model.vaoId);
|
||||
GLuint colorVboId;
|
||||
glGetVertexAttribIuiv(2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &colorVboId); // NOTE: Color VBO is buffer index 2
|
||||
glBindBuffer(GL_ARRAY_BUFFER, colorVboId);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*model.mesh.vertexCount, model.mesh.colors);
|
||||
|
||||
// OPTION 2: Just update one uniform on fragment shader
|
||||
// NOTE: It requires shader modification to add uniform (fragment shader) and create location point
|
||||
//glUniform4f(fragmentUniformColorLoc, (float)color.r/255, (float)color.g/255, (float)color.b/255, (float)color.a/255);
|
||||
*/
|
||||
|
||||
//TraceLog(DEBUG, "ShaderProgram: %i, VAO ID: %i, VertexCount: %i", shaderProgram, model.vaoId, model.mesh.vertexCount);
|
||||
|
||||
glBindVertexArray(model.vaoId);
|
||||
|
||||
// TODO: Update vertex color
|
||||
glBindBuffer(GL_ARRAY_BUFFER, linesBuffer[1]);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*model.mesh.vertexCount, model.mesh.colors);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, model.textureId);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, model.mesh.vertexCount);
|
||||
|
@ -989,8 +992,8 @@ void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scal
|
|||
// Initialize Graphics Device (OpenGL stuff)
|
||||
void rlglInitGraphicsDevice(int fbWidth, int fbHeight)
|
||||
{
|
||||
//glViewport(0, 0, fbWidth, fbHeight); // Set viewport width and height
|
||||
// NOTE: Not required, viewport will be full window space
|
||||
glViewport(0, 0, fbWidth, fbHeight); // Set viewport width and height
|
||||
// NOTE: Required! viewport must be recalculated if screen resized!
|
||||
|
||||
// NOTE: Don't confuse glViewport with the transformation matrix
|
||||
// NOTE: glViewport just defines the area of the context that you will actually draw to.
|
||||
|
@ -1052,7 +1055,7 @@ unsigned int rlglLoadTexture(unsigned char *data, int width, int height, bool ge
|
|||
// Check if width and height are power-of-two (POT)
|
||||
if (((width > 0) && ((width & (width - 1)) == 0)) && ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true;
|
||||
|
||||
if (!texIsPOT)
|
||||
if (genMipmaps && !texIsPOT)
|
||||
{
|
||||
TraceLog(WARNING, "[ID %i] Texture is not power-of-two, mipmaps can not be generated", id);
|
||||
|
||||
|
@ -1194,26 +1197,29 @@ unsigned int rlglLoadModel(VertexData mesh)
|
|||
// Create buffers for our vertex data (positions, texcoords, normals)
|
||||
glGenBuffers(3, vertexBuffer);
|
||||
|
||||
// Enable vertex attributes
|
||||
// Enable vertex attributes: position
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.vertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(vertexLoc);
|
||||
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
// Enable vertex attributes: texcoords
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*mesh.vertexCount, mesh.texcoords, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(texcoordLoc);
|
||||
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
// Enable vertex attributes: normals
|
||||
//glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[2]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.normals, GL_STATIC_DRAW);
|
||||
//glEnableVertexAttribArray(normalLoc);
|
||||
//glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
// Enable vertex attributes: colors
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*mesh.vertexCount, mesh.colors, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*mesh.vertexCount, mesh.colors, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(colorLoc);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
|
||||
|
||||
if (vaoModel > 0) TraceLog(INFO, "[ID %i] Model uploaded successfully to VRAM (GPU)", vaoModel);
|
||||
else TraceLog(WARNING, "Model could not be uploaded to VRAM (GPU)");
|
||||
|
@ -1408,34 +1414,34 @@ static char *TextFileRead(char *fn)
|
|||
static void InitializeBuffers()
|
||||
{
|
||||
// Initialize lines arrays (vertex position and color data)
|
||||
lines.vertices = (float *)malloc(sizeof(float)*3*2*MAX_LINES_BATCH); // 3 float by vertex, 2 vertex by line
|
||||
lines.colors = (float *)malloc(sizeof(float)*4*2*MAX_LINES_BATCH); // 4 float by color, 2 colors by line
|
||||
lines.vertices = (float *)malloc(sizeof(float)*3*2*MAX_LINES_BATCH); // 3 float by vertex, 2 vertex by line
|
||||
lines.colors = (unsigned char *)malloc(sizeof(unsigned char)*4*2*MAX_LINES_BATCH); // 4 float by color, 2 colors by line
|
||||
|
||||
for (int i = 0; i < (3*2*MAX_LINES_BATCH); i++) lines.vertices[i] = 0.0;
|
||||
for (int i = 0; i < (4*2*MAX_LINES_BATCH); i++) lines.colors[i] = 0.0;
|
||||
for (int i = 0; i < (4*2*MAX_LINES_BATCH); i++) lines.colors[i] = 0;
|
||||
|
||||
lines.vCounter = 0;
|
||||
lines.cCounter = 0;
|
||||
|
||||
// Initialize triangles arrays (vertex position and color data)
|
||||
triangles.vertices = (float *)malloc(sizeof(float)*3*3*MAX_TRIANGLES_BATCH); // 3 float by vertex, 3 vertex by triangle
|
||||
triangles.colors = (float *)malloc(sizeof(float)*4*3*MAX_TRIANGLES_BATCH); // 4 float by color, 3 colors by triangle
|
||||
triangles.vertices = (float *)malloc(sizeof(float)*3*3*MAX_TRIANGLES_BATCH); // 3 float by vertex, 3 vertex by triangle
|
||||
triangles.colors = (unsigned char *)malloc(sizeof(unsigned char)*4*3*MAX_TRIANGLES_BATCH); // 4 float by color, 3 colors by triangle
|
||||
|
||||
for (int i = 0; i < (3*3*MAX_TRIANGLES_BATCH); i++) triangles.vertices[i] = 0.0;
|
||||
for (int i = 0; i < (4*3*MAX_TRIANGLES_BATCH); i++) triangles.colors[i] = 0.0;
|
||||
for (int i = 0; i < (4*3*MAX_TRIANGLES_BATCH); i++) triangles.colors[i] = 0;
|
||||
|
||||
triangles.vCounter = 0;
|
||||
triangles.cCounter = 0;
|
||||
|
||||
// Initialize quads arrays (vertex position, texcoord and color data... and indexes)
|
||||
quads.vertices = (float *)malloc(sizeof(float)*3*4*MAX_QUADS_BATCH); // 3 float by vertex, 4 vertex by quad
|
||||
quads.texcoords = (float *)malloc(sizeof(float)*2*4*MAX_QUADS_BATCH); // 2 float by texcoord, 4 texcoord by quad
|
||||
quads.colors = (float *)malloc(sizeof(float)*4*4*MAX_QUADS_BATCH); // 4 float by color, 4 colors by quad
|
||||
quads.indices = (unsigned int *)malloc(sizeof(int)*6*MAX_QUADS_BATCH); // 6 int by quad (indices)
|
||||
quads.vertices = (float *)malloc(sizeof(float)*3*4*MAX_QUADS_BATCH); // 3 float by vertex, 4 vertex by quad
|
||||
quads.texcoords = (float *)malloc(sizeof(float)*2*4*MAX_QUADS_BATCH); // 2 float by texcoord, 4 texcoord by quad
|
||||
quads.colors = (unsigned char *)malloc(sizeof(unsigned char)*4*4*MAX_QUADS_BATCH); // 4 float by color, 4 colors by quad
|
||||
quads.indices = (unsigned int *)malloc(sizeof(int)*6*MAX_QUADS_BATCH); // 6 int by quad (indices)
|
||||
|
||||
for (int i = 0; i < (3*4*MAX_QUADS_BATCH); i++) quads.vertices[i] = 0.0;
|
||||
for (int i = 0; i < (2*4*MAX_QUADS_BATCH); i++) quads.texcoords[i] = 0.0;
|
||||
for (int i = 0; i < (4*4*MAX_QUADS_BATCH); i++) quads.colors[i] = 0.0;
|
||||
for (int i = 0; i < (4*4*MAX_QUADS_BATCH); i++) quads.colors[i] = 0;
|
||||
|
||||
int k = 0;
|
||||
|
||||
|
@ -1475,9 +1481,9 @@ static void InitializeVAOs()
|
|||
|
||||
// Lines - colors buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, linesBuffer[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2*MAX_LINES_BATCH, lines.colors, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*2*MAX_LINES_BATCH, lines.colors, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(colorLoc);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
|
||||
|
||||
TraceLog(INFO, "[ID %i] Lines VAO initialized successfully", vaoLines);
|
||||
//--------------------------------------------------------------
|
||||
|
@ -1496,9 +1502,9 @@ static void InitializeVAOs()
|
|||
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, trianglesBuffer[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(colorLoc);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
|
||||
|
||||
TraceLog(INFO, "[ID %i] Triangles VAO initialized successfully", vaoTriangles);
|
||||
//--------------------------------------------------------------
|
||||
|
@ -1522,46 +1528,15 @@ static void InitializeVAOs()
|
|||
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(colorLoc);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
|
||||
|
||||
// Fill index buffer
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadsBuffer[3]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*6*MAX_QUADS_BATCH, quads.indices, GL_STATIC_DRAW);
|
||||
|
||||
TraceLog(INFO, "[ID %i] Quads VAO initialized successfully", vaoQuads);
|
||||
|
||||
#ifdef USE_VBO_DOUBLE_BUFFERS
|
||||
// Initialize Quads VAO (Buffer B)
|
||||
glGenVertexArrays(1, &vaoQuadsB);
|
||||
glBindVertexArray(vaoQuadsB);
|
||||
|
||||
// Create buffers for our vertex data
|
||||
glGenBuffers(4, quadsBufferB);
|
||||
|
||||
// Enable vertex attributes
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBufferB[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_QUADS_BATCH, quads.vertices, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(vertexLoc);
|
||||
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBufferB[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*MAX_QUADS_BATCH, quads.texcoords, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(texcoordLoc);
|
||||
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBufferB[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(colorLoc);
|
||||
glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
|
||||
|
||||
// Fill index buffer
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadsBufferB[3]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*6*MAX_QUADS_BATCH, quads.indices, GL_STATIC_DRAW);
|
||||
|
||||
TraceLog(INFO, "[ID %i] Second Quads VAO successfully initilized (double buffering)", vaoQuadsB);
|
||||
#endif
|
||||
|
||||
// Unbind the current VAO
|
||||
glBindVertexArray(0);
|
||||
|
@ -1581,7 +1556,7 @@ static void UpdateBuffers()
|
|||
// Lines - colors buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, linesBuffer[1]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2*MAX_LINES_BATCH, lines.colors, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*lines.vCounter, lines.colors);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*lines.cCounter, lines.colors);
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
|
@ -1596,54 +1571,27 @@ static void UpdateBuffers()
|
|||
// Triangles - colors buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, trianglesBuffer[1]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*triangles.cCounter, triangles.colors);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*triangles.cCounter, triangles.colors);
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// Depending on useBufferB, update Buffer A or Buffer B
|
||||
#ifdef USE_VBO_DOUBLE_BUFFERS
|
||||
if (useBufferB)
|
||||
{
|
||||
// Activate Quads VAO (Buffer B)
|
||||
glBindVertexArray(vaoQuadsB);
|
||||
|
||||
// Quads - vertex positions buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBufferB[0]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_QUADS_BATCH, quads.vertices, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*quads.vCounter, quads.vertices);
|
||||
// Activate Quads VAO
|
||||
glBindVertexArray(vaoQuads);
|
||||
|
||||
// Quads - vertex positions buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[0]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_QUADS_BATCH, quads.vertices, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*quads.vCounter, quads.vertices);
|
||||
|
||||
// Quads - texture coordinates buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBufferB[1]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*MAX_QUADS_BATCH, quads.texcoords, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*quads.vCounter, quads.texcoords);
|
||||
|
||||
// Quads - colors buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBufferB[2]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*quads.vCounter, quads.colors);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Activate Quads VAO (Buffer A)
|
||||
glBindVertexArray(vaoQuads);
|
||||
|
||||
// Quads - vertex positions buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[0]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_QUADS_BATCH, quads.vertices, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*quads.vCounter, quads.vertices);
|
||||
|
||||
// Quads - texture coordinates buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[1]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*MAX_QUADS_BATCH, quads.texcoords, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*quads.vCounter, quads.texcoords);
|
||||
|
||||
// Quads - colors buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[2]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*quads.vCounter, quads.colors);
|
||||
}
|
||||
// Quads - texture coordinates buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[1]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*MAX_QUADS_BATCH, quads.texcoords, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*quads.vCounter, quads.texcoords);
|
||||
|
||||
// Quads - colors buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[2]);
|
||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*quads.vCounter, quads.colors);
|
||||
|
||||
// Another option would be using buffer mapping...
|
||||
//triangles.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
|
||||
|
|
|
@ -65,7 +65,7 @@ typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
|
|||
float *vertices; // 3 components per vertex
|
||||
float *texcoords; // 2 components per vertex
|
||||
float *normals; // 3 components per vertex
|
||||
float *colors;
|
||||
unsigned char *colors;
|
||||
} VertexData;
|
||||
|
||||
typedef struct Model {
|
||||
|
|
|
@ -230,12 +230,14 @@ SpriteFont LoadSpriteFont(const char* fileName)
|
|||
|
||||
// At this point we have a pixel array with all the data...
|
||||
|
||||
TraceLog(INFO, "[%s] SpriteFont image loaded: %i x %i", fileName, imgWidth, imgHeight);
|
||||
|
||||
// Process bitmap Font pixel data to get measures (Character array)
|
||||
// spriteFont.charSet data is filled inside the function and memory is allocated!
|
||||
int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
|
||||
|
||||
TraceLog(INFO, "[%s] SpriteFont data parsed correctly", fileName);
|
||||
TraceLog(INFO, "[%s] SpriteFont num chars detected: %i", numChars);
|
||||
TraceLog(INFO, "[%s] SpriteFont num chars detected: %i", fileName, numChars);
|
||||
|
||||
spriteFont.numChars = numChars;
|
||||
|
||||
|
|
|
@ -100,26 +100,30 @@ Image LoadImage(const char *fileName)
|
|||
// Force loading to 4 components (RGBA)
|
||||
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
|
||||
|
||||
// Convert array to pixel array for working convenience
|
||||
image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
|
||||
|
||||
int pix = 0;
|
||||
|
||||
for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
|
||||
if (imgData != NULL)
|
||||
{
|
||||
image.pixels[pix].r = imgData[i];
|
||||
image.pixels[pix].g = imgData[i+1];
|
||||
image.pixels[pix].b = imgData[i+2];
|
||||
image.pixels[pix].a = imgData[i+3];
|
||||
pix++;
|
||||
// Convert array to pixel array for working convenience
|
||||
image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
|
||||
|
||||
int pix = 0;
|
||||
|
||||
for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
|
||||
{
|
||||
image.pixels[pix].r = imgData[i];
|
||||
image.pixels[pix].g = imgData[i+1];
|
||||
image.pixels[pix].b = imgData[i+2];
|
||||
image.pixels[pix].a = imgData[i+3];
|
||||
pix++;
|
||||
}
|
||||
|
||||
stbi_image_free(imgData);
|
||||
|
||||
image.width = imgWidth;
|
||||
image.height = imgHeight;
|
||||
|
||||
TraceLog(INFO, "[%s] Image loaded successfully", fileName);
|
||||
}
|
||||
|
||||
stbi_image_free(imgData);
|
||||
|
||||
image.width = imgWidth;
|
||||
image.height = imgHeight;
|
||||
|
||||
TraceLog(INFO, "[%s] Image loaded successfully", fileName);
|
||||
else TraceLog(WARNING, "[%s] Image could not be loaded", fileName);
|
||||
}
|
||||
else if (strcmp(GetExtension(fileName),"dds") == 0)
|
||||
{
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 173 B |
|
@ -0,0 +1,83 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib test - Testing Heightmap Loading and Drawing
|
||||
*
|
||||
* This test has been created using raylib 1.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "../raylib.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
Vector3 position = { 0.5, 0.0, 0.5 };
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = {{ 7.0, 6.0, 7.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib test - Heightmap loading and drawing");
|
||||
|
||||
Image img = LoadImage("resources/cubesmap.png");
|
||||
Model map = LoadCubesmap(img);
|
||||
Texture2D texture = CreateTexture(img, false);
|
||||
UnloadImage(img);
|
||||
|
||||
SetModelTexture(&map, texture);
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KEY_UP)) camera.position.y += 0.2f;
|
||||
else if (IsKeyDown(KEY_DOWN)) camera.position.y -= 0.2f;
|
||||
|
||||
if (IsKeyDown(KEY_RIGHT)) camera.position.z += 0.2f;
|
||||
else if (IsKeyDown(KEY_LEFT)) camera.position.z -= 0.2f;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
Begin3dMode(camera);
|
||||
|
||||
//DrawCube(position, 1.0f, 1.0f, 1.0f, RED);
|
||||
|
||||
DrawModel(map, position, 1.0f, MAROON);
|
||||
|
||||
DrawGrid(10.0, 1.0); // Draw a grid
|
||||
|
||||
DrawGizmo(position);
|
||||
|
||||
End3dMode();
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(map); // Unload model
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -30,7 +30,7 @@ int main()
|
|||
Texture2D texture = CreateTexture(img, false);
|
||||
UnloadImage(img);
|
||||
|
||||
SetModelTexture(&map, texture);
|
||||
SetModelTexture(&map, texture);
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
@ -51,11 +51,11 @@ int main()
|
|||
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawModel(map, position, 0.5f, MAROON);
|
||||
DrawModel(map, position, 0.5f, MAROON);
|
||||
|
||||
DrawGrid(10.0, 1.0); // Draw a grid
|
||||
|
||||
DrawGizmo(position, false);
|
||||
DrawGizmo(position);
|
||||
|
||||
End3dMode();
|
||||
|
||||
|
@ -67,7 +67,7 @@ int main()
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(tex); // Unload texture
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(map); // Unload model
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
|
|
Loading…
Reference in New Issue