Update to version 1.1.1
Check CHANGELOG for a detailed list of changes
This commit is contained in:
parent
5e2e9aa23e
commit
0b03431c95
17 changed files with 851 additions and 331 deletions
19
CHANGELOG
19
CHANGELOG
|
@ -1,11 +1,28 @@
|
||||||
changelog
|
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: Only versions marked as 'Release' are available on release folder, updates are only available as source.
|
||||||
NOTE: Current Release includes all previous updates.
|
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)
|
Release: raylib 1.1.0 (19 April 2014)
|
||||||
-----------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
|
@ -34,4 +34,4 @@ contact
|
||||||
* Facebook: [http://www.facebook.com/raylibgames](http://www.facebook.com/raylibgames)
|
* 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
|
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.
|
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
|
building
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -143,4 +145,4 @@ The following people have contributed in some way to make raylib project a reali
|
||||||
- Victor Dual
|
- Victor Dual
|
||||||
- Marc Palau
|
- 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]
|
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);
|
DrawCubeWires((Vector3){-4, 0, -2}, 3, 6, 2, MAROON);
|
||||||
|
|
||||||
DrawSphere((Vector3){-1, 0, -2}, 1, GREEN);
|
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);
|
DrawCylinder((Vector3){4, 0, -2}, 1, 2, 3, 4, SKYBLUE);
|
||||||
DrawCylinderWires((Vector3){4, 0, -2}, 1, 2, 3, 4, DARKBLUE);
|
DrawCylinderWires((Vector3){4, 0, -2}, 1, 2, 3, 4, DARKBLUE);
|
||||||
|
|
|
@ -221,16 +221,16 @@ typedef struct Camera {
|
||||||
} Camera;
|
} Camera;
|
||||||
|
|
||||||
// Vertex data definning a mesh
|
// Vertex data definning a mesh
|
||||||
typedef struct {
|
typedef struct VertexData {
|
||||||
int vertexCount;
|
int vertexCount;
|
||||||
float *vertices; // 3 components per vertex
|
float *vertices; // 3 components per vertex
|
||||||
float *texcoords; // 2 components per vertex
|
float *texcoords; // 2 components per vertex
|
||||||
float *normals; // 3 components per vertex
|
float *normals; // 3 components per vertex
|
||||||
float *colors; // 4 components per vertex
|
unsigned char *colors; // 4 components per vertex
|
||||||
} VertexData;
|
} VertexData;
|
||||||
|
|
||||||
// 3d Model type
|
// 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 {
|
typedef struct Model {
|
||||||
VertexData mesh;
|
VertexData mesh;
|
||||||
unsigned int vaoId;
|
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)
|
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
|
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)
|
// 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 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 LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
|
||||||
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
||||||
|
Model LoadCubesmap(Image cubesmap); // Load a map image as a 3d model (cubes based)
|
||||||
void UnloadModel(Model model); // Unload 3d model from memory
|
void UnloadModel(Model model); // Unload 3d model from memory
|
||||||
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
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 Color background = { 0, 0, 0, 0 }; // Screen background color
|
||||||
|
|
||||||
|
static bool showLogo = false;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Other Modules Functions Declaration (required by core)
|
// 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 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 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 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
|
// 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
|
srand(time(NULL)); // Initialize random seed
|
||||||
|
|
||||||
ClearBackground(RAYWHITE); // Default background color for raylib games :P
|
ClearBackground(RAYWHITE); // Default background color for raylib games :P
|
||||||
|
|
||||||
|
// raylib logo appearing animation
|
||||||
|
if (showLogo)
|
||||||
|
{
|
||||||
|
SetTargetFPS(60);
|
||||||
|
LogoAnimation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close Window and Terminate Context
|
// 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};
|
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
|
// 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
|
// GLFW3 Error Callback, runs on GLFW3 error
|
||||||
static void ErrorCallback(int error, const char *description)
|
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
|
// GLFW3 Srolling Callback, runs on mouse wheel
|
||||||
|
@ -721,9 +737,15 @@ static void WindowSizeCallback(GLFWwindow* window, int width, int height)
|
||||||
int fbWidth, fbHeight;
|
int fbWidth, fbHeight;
|
||||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
||||||
|
|
||||||
// If window is resized, graphics device is re-initialized
|
// If window is resized, graphics device is re-initialized (but only ortho mode)
|
||||||
// NOTE: Aspect ratio does not change, so, image can be deformed
|
|
||||||
rlglInitGraphicsDevice(fbWidth, fbHeight);
|
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
|
// Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
|
||||||
|
@ -748,3 +770,122 @@ static void TakeScreenshot()
|
||||||
|
|
||||||
TraceLog(INFO, "[%s] Screenshot taken!", buffer);
|
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();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
}
|
575
src/models.c
575
src/models.c
|
@ -681,6 +681,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
||||||
vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||||
vData.normals = (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.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 vCounter = 0; // Used to count vertices float by float
|
||||||
int tcCounter = 0; // Used to count texcoords float by float
|
int tcCounter = 0; // Used to count texcoords float by float
|
||||||
|
@ -765,6 +766,332 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
||||||
|
|
||||||
// NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct
|
// NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct
|
||||||
|
|
||||||
|
// 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
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 model;
|
||||||
|
|
||||||
model.mesh = vData; // Model mesh is vertex data
|
model.mesh = vData; // Model mesh is vertex data
|
||||||
|
@ -945,141 +1272,81 @@ static VertexData LoadOBJ(const char *fileName)
|
||||||
|
|
||||||
objFile = fopen(fileName, "rt");
|
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: 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))
|
while(!feof(objFile))
|
||||||
{
|
{
|
||||||
fscanf(objFile, "%c", &dataType);
|
fscanf(objFile, "%c", &dataType);
|
||||||
|
|
||||||
switch(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);
|
fgets(comments, 200, objFile);
|
||||||
} break;
|
} 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;
|
|
||||||
case 'v':
|
case 'v':
|
||||||
{
|
{
|
||||||
fscanf(objFile, "%c", &dataType);
|
fscanf(objFile, "%c", &dataType);
|
||||||
|
|
||||||
if (dataType == 't') // Read texCoord
|
if (dataType == 't') // Read texCoord
|
||||||
{
|
{
|
||||||
fgets(comments, 200, objFile);
|
numTexCoords++;
|
||||||
fscanf(objFile, "%c", &dataType);
|
|
||||||
|
|
||||||
while (dataType == 'v')
|
|
||||||
{
|
|
||||||
fgets(comments, 200, objFile);
|
|
||||||
fscanf(objFile, "%c", &dataType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataType == '#')
|
|
||||||
{
|
|
||||||
fscanf(objFile, "%i", &numTexCoords);
|
|
||||||
}
|
|
||||||
|
|
||||||
fgets(comments, 200, objFile);
|
fgets(comments, 200, objFile);
|
||||||
}
|
}
|
||||||
else if (dataType == 'n') // Read normals
|
else if (dataType == 'n') // Read normals
|
||||||
{
|
{
|
||||||
fgets(comments, 200, objFile);
|
numNormals++;
|
||||||
fscanf(objFile, "%c", &dataType);
|
|
||||||
|
|
||||||
while (dataType == 'v')
|
|
||||||
{
|
|
||||||
fgets(comments, 200, objFile);
|
|
||||||
fscanf(objFile, "%c", &dataType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataType == '#')
|
|
||||||
{
|
|
||||||
fscanf(objFile, "%i", &numNormals);
|
|
||||||
}
|
|
||||||
|
|
||||||
fgets(comments, 200, objFile);
|
fgets(comments, 200, objFile);
|
||||||
}
|
}
|
||||||
else // Read vertex
|
else // Read vertex
|
||||||
{
|
{
|
||||||
fgets(comments, 200, objFile);
|
numVertex++;
|
||||||
fscanf(objFile, "%c", &dataType);
|
|
||||||
|
|
||||||
while (dataType == 'v')
|
|
||||||
{
|
|
||||||
fgets(comments, 200, objFile);
|
|
||||||
fscanf(objFile, "%c", &dataType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataType == '#')
|
|
||||||
{
|
|
||||||
fscanf(objFile, "%i", &numVertex);
|
|
||||||
}
|
|
||||||
|
|
||||||
fgets(comments, 200, objFile);
|
fgets(comments, 200, objFile);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case 'f':
|
case 'f':
|
||||||
{
|
{
|
||||||
|
numTriangles++;
|
||||||
fgets(comments, 200, objFile);
|
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;
|
} break;
|
||||||
default: 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
|
// Once we know the number of vertices to store, we create required arrays
|
||||||
Vector3 *midVertices = (Vector3 *)malloc(numVertex*sizeof(Vector3));
|
Vector3 *midVertices = (Vector3 *)malloc(numVertex*sizeof(Vector3));
|
||||||
Vector3 *midNormals = (Vector3 *)malloc(numNormals*sizeof(Vector3));
|
Vector3 *midNormals;
|
||||||
Vector2 *midTexCoords = (Vector2 *)malloc(numTexCoords*sizeof(Vector2));
|
if (numNormals > 0) midNormals = (Vector3 *)malloc(numNormals*sizeof(Vector3));
|
||||||
|
Vector2 *midTexCoords;
|
||||||
vData.vertexCount = numTriangles*3;
|
if (numTexCoords > 0) midTexCoords = (Vector2 *)malloc(numTexCoords*sizeof(Vector2));
|
||||||
|
|
||||||
// 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));
|
|
||||||
|
|
||||||
int countVertex = 0;
|
int countVertex = 0;
|
||||||
int countNormals = 0;
|
int countNormals = 0;
|
||||||
int countTexCoords = 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
|
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))
|
while(!feof(objFile))
|
||||||
{
|
{
|
||||||
fscanf(objFile, "%c", &dataType);
|
fscanf(objFile, "%c", &dataType);
|
||||||
|
|
||||||
switch(dataType)
|
switch(dataType)
|
||||||
{
|
{
|
||||||
case '#':
|
case '#': case 'o': case 'g': case 's': case 'm': case 'u': case 'f': fgets(comments, 200, objFile); break;
|
||||||
{
|
|
||||||
fgets(comments, 200, objFile);
|
|
||||||
} break;
|
|
||||||
case 'v':
|
case 'v':
|
||||||
{
|
{
|
||||||
fscanf(objFile, "%c", &dataType);
|
fscanf(objFile, "%c", &dataType);
|
||||||
|
@ -1108,60 +1375,107 @@ static VertexData LoadOBJ(const char *fileName)
|
||||||
fscanf(objFile, "%c", &dataType);
|
fscanf(objFile, "%c", &dataType);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case 'f':
|
default: break;
|
||||||
{
|
}
|
||||||
// At this point all vertex data (v, vt, vn) have been gathered on midVertices, midTexCoords, midNormals
|
}
|
||||||
|
|
||||||
|
// 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
|
// Now we can organize that data into our VertexData struct
|
||||||
|
|
||||||
int vNum, vtNum, vnNum;
|
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);
|
fscanf(objFile, "%c", &dataType);
|
||||||
fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
|
|
||||||
|
|
||||||
vData.vertices[vCounter] = midVertices[vNum-1].x;
|
switch(dataType)
|
||||||
vData.vertices[vCounter + 1] = midVertices[vNum-1].y;
|
{
|
||||||
vData.vertices[vCounter + 2] = midVertices[vNum-1].z;
|
case '#': case 'o': case 'g': case 's': case 'm': case 'u': case 'v': fgets(comments, 200, objFile); break;
|
||||||
|
case 'f':
|
||||||
|
{
|
||||||
|
// NOTE: It could be that OBJ does not have normals or texcoords defined!
|
||||||
|
|
||||||
|
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;
|
vCounter += 3;
|
||||||
|
|
||||||
vData.normals[nCounter] = midNormals[vnNum-1].x;
|
if (numNormals > 0)
|
||||||
vData.normals[nCounter + 1] = midNormals[vnNum-1].y;
|
{
|
||||||
vData.normals[nCounter + 2] = midNormals[vnNum-1].z;
|
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;
|
nCounter += 3;
|
||||||
|
vData.normals[nCounter] = midNormals[vnNum[1]-1].x;
|
||||||
vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x;
|
vData.normals[nCounter + 1] = midNormals[vnNum[1]-1].y;
|
||||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y;
|
vData.normals[nCounter + 2] = midNormals[vnNum[1]-1].z;
|
||||||
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;
|
nCounter += 3;
|
||||||
|
vData.normals[nCounter] = midNormals[vnNum[2]-1].x;
|
||||||
vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x;
|
vData.normals[nCounter + 1] = midNormals[vnNum[2]-1].y;
|
||||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y;
|
vData.normals[nCounter + 2] = midNormals[vnNum[2]-1].z;
|
||||||
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;
|
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.texcoords[tcCounter] = midTexCoords[vtNum-1].x;
|
vData.normals[nCounter] = norm.x;
|
||||||
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numTexCoords > 0)
|
||||||
|
{
|
||||||
|
vData.texcoords[tcCounter] = midTexCoords[vtNum[0]-1].x;
|
||||||
|
vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum[0]-1].y;
|
||||||
tcCounter += 2;
|
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;
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -1169,8 +1483,11 @@ static VertexData LoadOBJ(const char *fileName)
|
||||||
|
|
||||||
fclose(objFile);
|
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
|
// 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
|
// Now we can free temp mid* arrays
|
||||||
free(midVertices);
|
free(midVertices);
|
||||||
|
|
|
@ -226,11 +226,11 @@ typedef struct VertexData {
|
||||||
float *vertices; // 3 components per vertex
|
float *vertices; // 3 components per vertex
|
||||||
float *texcoords; // 2 components per vertex
|
float *texcoords; // 2 components per vertex
|
||||||
float *normals; // 3 components per vertex
|
float *normals; // 3 components per vertex
|
||||||
float *colors; // 4 components per vertex
|
unsigned char *colors; // 4 components per vertex
|
||||||
} VertexData;
|
} VertexData;
|
||||||
|
|
||||||
// 3d Model type
|
// 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 {
|
typedef struct Model {
|
||||||
VertexData mesh;
|
VertexData mesh;
|
||||||
unsigned int vaoId;
|
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)
|
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
|
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)
|
// 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 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 LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
|
||||||
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
||||||
|
Model LoadCubesmap(Image cubesmap); // Load a map image as a 3d model (cubes based)
|
||||||
void UnloadModel(Model model); // Unload 3d model from memory
|
void UnloadModel(Model model); // Unload 3d model from memory
|
||||||
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
||||||
|
|
||||||
|
|
220
src/rlgl.c
220
src/rlgl.c
|
@ -58,8 +58,6 @@
|
||||||
|
|
||||||
//#include "glad.h" // Other extensions loading lib? --> REVIEW
|
//#include "glad.h" // Other extensions loading lib? --> REVIEW
|
||||||
|
|
||||||
#define USE_VBO_DOUBLE_BUFFERS // Enable VBO double buffers usage --> REVIEW!
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -77,7 +75,7 @@ typedef struct {
|
||||||
int vCounter;
|
int vCounter;
|
||||||
int cCounter;
|
int cCounter;
|
||||||
float *vertices; // 3 components per vertex
|
float *vertices; // 3 components per vertex
|
||||||
float *colors; // 4 components per vertex
|
unsigned char *colors; // 4 components per vertex
|
||||||
} VertexPositionColorBuffer;
|
} VertexPositionColorBuffer;
|
||||||
|
|
||||||
// Vertex buffer (position + texcoords + color arrays)
|
// Vertex buffer (position + texcoords + color arrays)
|
||||||
|
@ -88,7 +86,7 @@ typedef struct {
|
||||||
int cCounter;
|
int cCounter;
|
||||||
float *vertices; // 3 components per vertex
|
float *vertices; // 3 components per vertex
|
||||||
float *texcoords; // 2 components per vertex
|
float *texcoords; // 2 components per vertex
|
||||||
float *colors; // 4 components per vertex
|
unsigned char *colors; // 4 components per vertex
|
||||||
} VertexPositionColorTextureBuffer;
|
} VertexPositionColorTextureBuffer;
|
||||||
|
|
||||||
// Vertex buffer (position + texcoords + normals arrays)
|
// Vertex buffer (position + texcoords + normals arrays)
|
||||||
|
@ -110,7 +108,7 @@ typedef struct {
|
||||||
int cCounter;
|
int cCounter;
|
||||||
float *vertices; // 3 components per vertex
|
float *vertices; // 3 components per vertex
|
||||||
float *texcoords; // 2 components per vertex
|
float *texcoords; // 2 components per vertex
|
||||||
float *colors; // 4 components per vertex
|
unsigned char *colors; // 4 components per vertex
|
||||||
unsigned int *indices; // 6 indices per quad
|
unsigned int *indices; // 6 indices per quad
|
||||||
} VertexPositionColorTextureIndexBuffer;
|
} VertexPositionColorTextureIndexBuffer;
|
||||||
|
|
||||||
|
@ -165,13 +163,6 @@ static GLuint linesBuffer[2];
|
||||||
static GLuint trianglesBuffer[2];
|
static GLuint trianglesBuffer[2];
|
||||||
static GLuint quadsBuffer[4];
|
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 DrawCall *draws;
|
||||||
static int drawsCounter;
|
static int drawsCounter;
|
||||||
|
|
||||||
|
@ -566,7 +557,7 @@ void rlNormal3f(float x, float y, float z)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define one vertex (color)
|
// 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)
|
switch (currentDrawMode)
|
||||||
{
|
{
|
||||||
|
@ -605,15 +596,15 @@ void rlColor4f(float x, float y, float z, float w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define one vertex (color)
|
// 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)
|
// Define one vertex (color)
|
||||||
void rlColor3f(float x, float y, float z)
|
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
|
#endif
|
||||||
|
@ -826,33 +817,15 @@ void rlglClose()
|
||||||
|
|
||||||
void rlglDraw()
|
void rlglDraw()
|
||||||
{
|
{
|
||||||
|
UpdateBuffers();
|
||||||
|
|
||||||
glUseProgram(shaderProgram); // Use our shader
|
glUseProgram(shaderProgram); // Use our shader
|
||||||
|
|
||||||
glUniformMatrix4fv(projectionMatrixLoc, 1, false, GetMatrixVector(projection));
|
glUniformMatrix4fv(projectionMatrixLoc, 1, false, GetMatrixVector(projection));
|
||||||
glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelview));
|
glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelview));
|
||||||
glUniform1i(textureLoc, 0);
|
glUniform1i(textureLoc, 0);
|
||||||
|
|
||||||
UpdateBuffers();
|
// NOTE: We draw in this order: textured quads, triangles shapes, lines
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quads.vCounter > 0)
|
if (quads.vCounter > 0)
|
||||||
{
|
{
|
||||||
|
@ -860,14 +833,7 @@ void rlglDraw()
|
||||||
int numIndicesToProcess = 0;
|
int numIndicesToProcess = 0;
|
||||||
int indicesOffset = 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);
|
//TraceLog(DEBUG, "Draws required per frame: %i", drawsCounter);
|
||||||
|
|
||||||
|
@ -885,9 +851,30 @@ void rlglDraw()
|
||||||
|
|
||||||
indicesOffset += draws[i].vertexCount/4*6;
|
indicesOffset += draws[i].vertexCount/4*6;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
glBindVertexArray(0); // Unbind VAO
|
glBindVertexArray(0); // Unbind VAO
|
||||||
|
|
||||||
// Reset draws counter
|
// Reset draws counter
|
||||||
|
@ -905,11 +892,6 @@ void rlglDraw()
|
||||||
quads.vCounter = 0;
|
quads.vCounter = 0;
|
||||||
quads.tcCounter = 0;
|
quads.tcCounter = 0;
|
||||||
quads.cCounter = 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
|
#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
|
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
|
glTexCoordPointer(2, GL_FLOAT, 0, model.mesh.texcoords); // Pointer to texture coords array
|
||||||
glNormalPointer(GL_FLOAT, 0, model.mesh.normals); // Pointer to normals 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);
|
//TraceLog(DEBUG, "Drawing model.mesh, VertexCount: %i", model.mesh.vertexCount);
|
||||||
|
|
||||||
|
@ -967,14 +949,35 @@ void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scal
|
||||||
glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelviewworld));
|
glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelviewworld));
|
||||||
glUniform1i(textureLoc, 0);
|
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);
|
//TraceLog(DEBUG, "ShaderProgram: %i, VAO ID: %i, VertexCount: %i", shaderProgram, model.vaoId, model.mesh.vertexCount);
|
||||||
|
|
||||||
glBindVertexArray(model.vaoId);
|
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);
|
glBindTexture(GL_TEXTURE_2D, model.textureId);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, model.mesh.vertexCount);
|
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)
|
// Initialize Graphics Device (OpenGL stuff)
|
||||||
void rlglInitGraphicsDevice(int fbWidth, int fbHeight)
|
void rlglInitGraphicsDevice(int fbWidth, int fbHeight)
|
||||||
{
|
{
|
||||||
//glViewport(0, 0, fbWidth, fbHeight); // Set viewport width and height
|
glViewport(0, 0, fbWidth, fbHeight); // Set viewport width and height
|
||||||
// NOTE: Not required, viewport will be full window space
|
// NOTE: Required! viewport must be recalculated if screen resized!
|
||||||
|
|
||||||
// NOTE: Don't confuse glViewport with the transformation matrix
|
// NOTE: Don't confuse glViewport with the transformation matrix
|
||||||
// NOTE: glViewport just defines the area of the context that you will actually draw to.
|
// 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)
|
// 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 (((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);
|
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)
|
// Create buffers for our vertex data (positions, texcoords, normals)
|
||||||
glGenBuffers(3, vertexBuffer);
|
glGenBuffers(3, vertexBuffer);
|
||||||
|
|
||||||
// Enable vertex attributes
|
// Enable vertex attributes: position
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
|
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.vertices, GL_STATIC_DRAW);
|
||||||
glEnableVertexAttribArray(vertexLoc);
|
glEnableVertexAttribArray(vertexLoc);
|
||||||
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||||
|
|
||||||
|
// Enable vertex attributes: texcoords
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
|
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*mesh.vertexCount, mesh.texcoords, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*mesh.vertexCount, mesh.texcoords, GL_STATIC_DRAW);
|
||||||
glEnableVertexAttribArray(texcoordLoc);
|
glEnableVertexAttribArray(texcoordLoc);
|
||||||
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||||
|
|
||||||
|
// Enable vertex attributes: normals
|
||||||
//glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[2]);
|
//glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[2]);
|
||||||
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.normals, GL_STATIC_DRAW);
|
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.vertexCount, mesh.normals, GL_STATIC_DRAW);
|
||||||
//glEnableVertexAttribArray(normalLoc);
|
//glEnableVertexAttribArray(normalLoc);
|
||||||
//glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
//glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||||
|
|
||||||
|
// Enable vertex attributes: colors
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[2]);
|
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);
|
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);
|
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)");
|
else TraceLog(WARNING, "Model could not be uploaded to VRAM (GPU)");
|
||||||
|
@ -1409,20 +1415,20 @@ static void InitializeBuffers()
|
||||||
{
|
{
|
||||||
// Initialize lines arrays (vertex position and color data)
|
// 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.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.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 < (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.vCounter = 0;
|
||||||
lines.cCounter = 0;
|
lines.cCounter = 0;
|
||||||
|
|
||||||
// Initialize triangles arrays (vertex position and color data)
|
// 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.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.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 < (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.vCounter = 0;
|
||||||
triangles.cCounter = 0;
|
triangles.cCounter = 0;
|
||||||
|
@ -1430,12 +1436,12 @@ static void InitializeBuffers()
|
||||||
// Initialize quads arrays (vertex position, texcoord and color data... and indexes)
|
// 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.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.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.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)
|
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 < (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 < (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;
|
int k = 0;
|
||||||
|
|
||||||
|
@ -1475,9 +1481,9 @@ static void InitializeVAOs()
|
||||||
|
|
||||||
// Lines - colors buffer
|
// Lines - colors buffer
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, linesBuffer[1]);
|
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);
|
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);
|
TraceLog(INFO, "[ID %i] Lines VAO initialized successfully", vaoLines);
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
@ -1496,9 +1502,9 @@ static void InitializeVAOs()
|
||||||
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, trianglesBuffer[1]);
|
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);
|
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);
|
TraceLog(INFO, "[ID %i] Triangles VAO initialized successfully", vaoTriangles);
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
@ -1522,9 +1528,9 @@ static void InitializeVAOs()
|
||||||
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[2]);
|
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);
|
glEnableVertexAttribArray(colorLoc);
|
||||||
glVertexAttribPointer(colorLoc, 4, GL_FLOAT, 0, 0, 0);
|
glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
|
||||||
|
|
||||||
// Fill index buffer
|
// Fill index buffer
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadsBuffer[3]);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadsBuffer[3]);
|
||||||
|
@ -1532,37 +1538,6 @@ static void InitializeVAOs()
|
||||||
|
|
||||||
TraceLog(INFO, "[ID %i] Quads VAO initialized successfully", vaoQuads);
|
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
|
// Unbind the current VAO
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
@ -1581,7 +1556,7 @@ static void UpdateBuffers()
|
||||||
// Lines - colors buffer
|
// Lines - colors buffer
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, linesBuffer[1]);
|
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(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,36 +1571,11 @@ static void UpdateBuffers()
|
||||||
// Triangles - colors buffer
|
// Triangles - colors buffer
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, trianglesBuffer[1]);
|
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(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
|
// Activate Quads VAO
|
||||||
#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);
|
|
||||||
|
|
||||||
// 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);
|
glBindVertexArray(vaoQuads);
|
||||||
|
|
||||||
// Quads - vertex positions buffer
|
// Quads - vertex positions buffer
|
||||||
|
@ -1641,9 +1591,7 @@ static void UpdateBuffers()
|
||||||
// Quads - colors buffer
|
// Quads - colors buffer
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, quadsBuffer[2]);
|
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(float)*4*4*MAX_QUADS_BATCH, quads.colors, GL_DYNAMIC_DRAW);
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*quads.vCounter, quads.colors);
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*quads.vCounter, quads.colors);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Another option would be using buffer mapping...
|
// Another option would be using buffer mapping...
|
||||||
//triangles.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
|
//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 *vertices; // 3 components per vertex
|
||||||
float *texcoords; // 2 components per vertex
|
float *texcoords; // 2 components per vertex
|
||||||
float *normals; // 3 components per vertex
|
float *normals; // 3 components per vertex
|
||||||
float *colors;
|
unsigned char *colors;
|
||||||
} VertexData;
|
} VertexData;
|
||||||
|
|
||||||
typedef struct Model {
|
typedef struct Model {
|
||||||
|
|
|
@ -230,12 +230,14 @@ SpriteFont LoadSpriteFont(const char* fileName)
|
||||||
|
|
||||||
// At this point we have a pixel array with all the data...
|
// 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)
|
// Process bitmap Font pixel data to get measures (Character array)
|
||||||
// spriteFont.charSet data is filled inside the function and memory is allocated!
|
// spriteFont.charSet data is filled inside the function and memory is allocated!
|
||||||
int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
|
int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
|
||||||
|
|
||||||
TraceLog(INFO, "[%s] SpriteFont data parsed correctly", fileName);
|
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;
|
spriteFont.numChars = numChars;
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,8 @@ Image LoadImage(const char *fileName)
|
||||||
// Force loading to 4 components (RGBA)
|
// Force loading to 4 components (RGBA)
|
||||||
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
|
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
|
||||||
|
|
||||||
|
if (imgData != NULL)
|
||||||
|
{
|
||||||
// Convert array to pixel array for working convenience
|
// Convert array to pixel array for working convenience
|
||||||
image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
|
image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
|
||||||
|
|
||||||
|
@ -121,6 +123,8 @@ Image LoadImage(const char *fileName)
|
||||||
|
|
||||||
TraceLog(INFO, "[%s] Image loaded successfully", fileName);
|
TraceLog(INFO, "[%s] Image loaded successfully", fileName);
|
||||||
}
|
}
|
||||||
|
else TraceLog(WARNING, "[%s] Image could not be loaded", fileName);
|
||||||
|
}
|
||||||
else if (strcmp(GetExtension(fileName),"dds") == 0)
|
else if (strcmp(GetExtension(fileName),"dds") == 0)
|
||||||
{
|
{
|
||||||
// NOTE: DDS uncompressed images can also be loaded (discarding mipmaps...)
|
// NOTE: DDS uncompressed images can also be loaded (discarding mipmaps...)
|
||||||
|
|
BIN
tests/resources/cubesmap.png
Normal file
BIN
tests/resources/cubesmap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 173 B |
83
tests/test_cubesmap.c
Normal file
83
tests/test_cubesmap.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -55,7 +55,7 @@ int main()
|
||||||
|
|
||||||
DrawGrid(10.0, 1.0); // Draw a grid
|
DrawGrid(10.0, 1.0); // Draw a grid
|
||||||
|
|
||||||
DrawGizmo(position, false);
|
DrawGizmo(position);
|
||||||
|
|
||||||
End3dMode();
|
End3dMode();
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ int main()
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadTexture(tex); // Unload texture
|
UnloadTexture(texture); // Unload texture
|
||||||
UnloadModel(map); // Unload model
|
UnloadModel(map); // Unload model
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue