aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2014-04-04 20:11:57 +0200
committerraysan5 <raysan5@gmail.com>2014-04-04 20:11:57 +0200
commitc04f37d0f5f75c3e112d71444e589513396c9d0f (patch)
tree22390fc34202b679cc72319b3f8b99214be98905 /src
parent79cf87d91da236fbff71357191cc11bb3eddab8a (diff)
downloadraylib-c04f37d0f5f75c3e112d71444e589513396c9d0f.tar.gz
raylib-c04f37d0f5f75c3e112d71444e589513396c9d0f.zip
Adapt multiple functions to rlgl
Nearly a complete rework of Models module Some teaks on multiple functions
Diffstat (limited to 'src')
-rw-r--r--src/audio.c4
-rw-r--r--src/models.c866
-rw-r--r--src/raylib.h6
-rw-r--r--src/rlgl.c150
-rw-r--r--src/rlgl.h46
-rw-r--r--src/shapes.c29
-rw-r--r--src/text.c1
-rw-r--r--src/textures.c102
8 files changed, 755 insertions, 449 deletions
diff --git a/src/audio.c b/src/audio.c
index 4b75942f..ac6fc2b3 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -131,7 +131,7 @@ Sound LoadSound(char *fileName)
// NOTE: Buffer space is allocated inside LoadWAV, Wave must be freed
Wave wave = LoadWAV(fileName);
- ALenum format;
+ ALenum format = 0;
// The OpenAL format is worked out by looking at the number of channels and the bits per sample
if (wave.channels == 1)
{
@@ -257,7 +257,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
free(data);
// Convert wave to Sound (OpenAL)
- ALenum format;
+ ALenum format = 0;
// The OpenAL format is worked out by looking at the number of channels and the bits per sample
if (wave.channels == 1)
diff --git a/src/models.c b/src/models.c
index e1b80617..fb8f114d 100644
--- a/src/models.c
+++ b/src/models.c
@@ -31,7 +31,6 @@
#include <math.h> // Used for sin, cos, tan
#include "raymath.h" // Required for data type Matrix and Matrix functions
-
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
//----------------------------------------------------------------------------------
@@ -42,30 +41,7 @@
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
-#ifdef USE_OPENGL_11
- struct Model {
- int numVertices;
- Vector3 *vertices;
- Vector2 *texcoords;
- Vector3 *normals;
- };
-#else
- struct Model {
- int numVertices;
- Vector3 *vertices;
- Vector2 *texcoords;
- Vector3 *normals;
- };
-
-/*
- struct Model
- {
- GLUint vaoId;
- Matrix transform;
- int polyMode;
- }
-*/
-#endif
+// ...
//----------------------------------------------------------------------------------
// Global Variables Definition
@@ -85,25 +61,167 @@ static float GetHeightValue(Color pixel);
// NOTE: Cube position is the center position
void DrawCube(Vector3 position, float width, float height, float lenght, Color color)
{
- // THIS WORKS!
-/*
- Matrix mat = MatrixTranslate(2.0, 0.0, 0.0);
- MatrixTranspose(&mat);
- VectorTransform(&position, mat);
-
- PrintMatrix(mat);
-*/
-
float x = position.x;
float y = position.y;
float z = position.z;
rlPushMatrix();
+
+ // NOTE: Be careful! Function order matters (scale, translate, rotate)
+ //rlScalef(2.0f, 2.0f, 2.0f);
+ //rlTranslatef(0.0f, 0.0f, 0.0f);
+ //rlRotatef(45, 0, 1, 0);
+
+ rlBegin(RL_TRIANGLES);
+ rlColor4ub(color.r, color.g, color.b, color.a);
+
+ // Front Face -----------------------------------------------------
+ rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left
+ rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
+ rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
+
+ rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Right
+ rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
+ rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
+
+ // Back Face ------------------------------------------------------
+ rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Left
+ rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
+ rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
+
+ rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
+ rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
+ rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
+
+ // Top Face -------------------------------------------------------
+ rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
+ rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Bottom Left
+ rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Bottom Right
+
+ rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
+ rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
+ rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Bottom Right
+
+ // Bottom Face ----------------------------------------------------
+ rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Top Left
+ rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
+ rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left
+
+ rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Top Right
+ rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
+ rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Top Left
+
+ // Right face -----------------------------------------------------
+ rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
+ rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
+ rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Left
+
+ rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Left
+ rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
+ rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Left
+
+ // Left Face ------------------------------------------------------
+ rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Right
+ rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
+ rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Right
+
+ rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left
+ rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
+ rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Right
+ rlEnd();
+ rlPopMatrix();
+}
+
+// Draw cube (Vector version)
+void DrawCubeV(Vector3 position, Vector3 size, Color color)
+{
+ DrawCube(position, size.x, size.y, size.z, color);
+}
+
+// Draw cube wires
+void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color)
+{
+ float x = position.x;
+ float y = position.y;
+ float z = position.z;
+
+ rlPushMatrix();
+
+ //rlRotatef(45, 0, 1, 0);
+
+ rlBegin(RL_LINES);
+ rlColor4ub(color.r, color.g, color.b, color.a);
+
+ // Front Face -----------------------------------------------------
+ // Bottom Line
+ rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left
+ rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
+
+ // Left Line
+ rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
+ rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Right
+
+ // Top Line
+ rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Right
+ rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
+
+ // Right Line
+ rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
+ rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left
+ // Back Face ------------------------------------------------------
+ // Bottom Line
+ rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Left
+ rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
+
+ // Left Line
+ rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
+ rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
+
+ // Top Line
+ rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
+ rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
+
+ // Right Line
+ rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
+ rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Left
+
+ // Top Face -------------------------------------------------------
+ // Left Line
+ rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left Front
+ rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left Back
+
+ // Right Line
+ rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Right Front
+ rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right Back
+
+ // Bottom Face ---------------------------------------------------
+ // Left Line
+ rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Top Left Front
+ rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Top Left Back
+
+ // Right Line
+ rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Top Right Front
+ rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Top Right Back
+ rlEnd();
+ rlPopMatrix();
+}
+
+// Draw cube
+// NOTE: Cube position is the center position
+void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color)
+{
+ float x = position.x;
+ float y = position.y;
+ float z = position.z;
+
+ rlEnableTexture(texture.glId);
+
+ rlPushMatrix();
// NOTE: Be careful! Function order matters (scale, translate, rotate)
//rlScalef(2.0f, 2.0f, 2.0f);
//rlTranslatef(2.0f, 0.0f, 0.0f);
- rlRotatef(45, 0, 1, 0);
+ //rlRotatef(45, 0, 1, 0);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
@@ -145,22 +263,8 @@ void DrawCube(Vector3 position, float width, float height, float lenght, Color c
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left Of The Texture and Quad
rlEnd();
rlPopMatrix();
-}
-
-// Draw cube (Vector version)
-void DrawCubeV(Vector3 position, Vector3 size, Color color)
-{
- DrawCube(position, size.x, size.y, size.z, color);
-}
-
-// Draw cube wires
-void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color)
-{
- // TODO: Draw cube using RL_LINES!
- //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- //DrawCube(position, width, height, lenght, color);
- //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ rlDisableTexture();
}
// Draw sphere
@@ -172,42 +276,37 @@ void DrawSphere(Vector3 centerPos, float radius, Color color)
// Draw sphere with extended parameters
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color)
{
- float lat0, z0, zr0;
- float lat1, z1, zr1;
- float lng, x, y;
-
- // TODO: Review vertex translate/rotate/scale mechanism
-
rlPushMatrix();
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
- rlRotatef(90, 1, 0, 0);
+ //rlRotatef(rotation, 0, 1, 0);
rlScalef(radius, radius, radius);
- rlBegin(GL_QUAD_STRIP);
-
+ rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
- for(int i = 0; i <= rings; i++)
+ for(int i = 0; i < 2 * rings + 1; i ++)
{
- lat0 = PI * (-0.5 + (float)(i - 1) / rings);
- z0 = sin(lat0);
- zr0 = cos(lat0);
-
- lat1 = PI * (-0.5 + (float)i / rings);
- z1 = sin(lat1);
- zr1 = cos(lat1);
-
- for(int j = 0; j <= slices; j++)
+ for(int j = 0; j < slices; j++)
{
- lng = 2 * PI * (float)(j - 1) / slices;
- x = cos(lng);
- y = sin(lng);
-
- rlNormal3f(x * zr0, y * zr0, z0);
- rlVertex3f(x * zr0, y * zr0, z0);
-
- rlNormal3f(x * zr1, y * zr1, z1);
- rlVertex3f(x * zr1, y * zr1, z1);
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*i)) * sin(DEG2RAD*(j*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*i)) * radius,
+ cos(DEG2RAD*(270+(90/rings)*i)) * cos(DEG2RAD*(j*360/slices)) * radius);
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*(i+1))) * radius,
+ cos(DEG2RAD*(270+(90/rings)*(i+1))) * cos(DEG2RAD*((j+1)*360/slices)) * radius);
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*(i+1))) * sin(DEG2RAD*(j*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*(i+1))) * radius,
+ cos(DEG2RAD*(270+(90/rings)*(i+1))) * cos(DEG2RAD*(j*360/slices)) * radius);
+
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*i)) * sin(DEG2RAD*(j*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*i)) * radius,
+ cos(DEG2RAD*(270+(90/rings)*i)) * cos(DEG2RAD*(j*360/slices)) * radius);
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*(i))) * sin(DEG2RAD*((j+1)*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*(i))) * radius,
+ cos(DEG2RAD*(270+(90/rings)*(i))) * cos(DEG2RAD*((j+1)*360/slices)) * radius);
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*(i+1))) * radius,
+ cos(DEG2RAD*(270+(90/rings)*(i+1))) * cos(DEG2RAD*((j+1)*360/slices)) * radius);
}
}
rlEnd();
@@ -215,134 +314,136 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
}
// Draw sphere wires
-void DrawSphereWires(Vector3 centerPos, float radius, Color color)
-{
- // TODO: Draw sphere using RL_LINES!
-
- //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- //DrawSphere(centerPos, radius, color);
- //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-}
-
-// Draw a cylinder/cone
-void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color) // Could be used for pyramid and cone!
+void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color)
{
- Vector3 a = { position.x, position.y + height, position.z };
- Vector3 d = { 0.0f, 1.0f, 0.0f };
- Vector3 p;
- Vector3 c = { a.x + (-d.x * height), a.y + (-d.y * height), a.z + (-d.z * height) }; //= a + (-d * h);
- Vector3 e0 = VectorPerpendicular(d);
- Vector3 e1 = VectorCrossProduct(e0, d);
- float angInc = 360.0 / slices * DEG2RAD;
-
- if (radiusTop == 0) // Draw pyramid or cone
- {
- //d – axis defined as a normalized vector from base to apex
- //a – position of apex (top point)
- //h – height
- //rd – radius of directrix
- //n – number of radial "slices"
-
- // TODO: Review drawing to use RL_TRIANGLES
+ rlPushMatrix();
+ rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
+ //rlRotatef(rotation, 0, 1, 0);
+ rlScalef(radius, radius, radius);
- // Draw cone top
- rlBegin(GL_TRIANGLE_FAN);
+ rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
- rlVertex3f(a.x, a.y, a.z);
- for (int i = 0; i <= slices; i++)
+ for(int i = 0; i < 2 * rings + 1; i ++)
{
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
- rlVertex3f(p.x, p.y, p.z);
+ for(int j = 0; j < slices; j++)
+ {
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*i)) * sin(DEG2RAD*(j*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*i)) * radius,
+ cos(DEG2RAD*(270+(90/rings)*i)) * cos(DEG2RAD*(j*360/slices)) * radius);
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*(i+1))) * radius,
+ cos(DEG2RAD*(270+(90/rings)*(i+1))) * cos(DEG2RAD*((j+1)*360/slices)) * radius);
+
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*(i+1))) * radius,
+ cos(DEG2RAD*(270+(90/rings)*(i+1))) * cos(DEG2RAD*((j+1)*360/slices)) * radius);
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*(i+1))) * sin(DEG2RAD*(j*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*(i+1))) * radius,
+ cos(DEG2RAD*(270+(90/rings)*(i+1))) * cos(DEG2RAD*(j*360/slices)) * radius);
+
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*(i+1))) * sin(DEG2RAD*(j*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*(i+1))) * radius,
+ cos(DEG2RAD*(270+(90/rings)*(i+1))) * cos(DEG2RAD*(j*360/slices)) * radius);
+ rlVertex3f(cos(DEG2RAD*(270+(90/rings)*i)) * sin(DEG2RAD*(j*360/slices)) * radius,
+ sin(DEG2RAD*(270+(90/rings)*i)) * radius,
+ cos(DEG2RAD*(270+(90/rings)*i)) * cos(DEG2RAD*(j*360/slices)) * radius);
+ }
}
rlEnd();
-
- // Draw cone bottom
- rlBegin(GL_TRIANGLE_FAN);
+ rlPopMatrix();
+}
+
+// Draw a cylinder
+// NOTE: It could be also used for pyramid and cone
+void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color)
+{
+ if (sides < 3) sides = 3;
+
+ rlPushMatrix();
+ rlTranslatef(position.x, position.y, position.z);
+
+ rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
- rlVertex3f(c.x, c.y, c.z);
-
- for (int i = slices; i >= 0; i--)
+
+ if (radiusTop > 0)
{
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
- rlVertex3f(p.x, p.y, p.z);
+ // Draw Body -------------------------------------------------------------------------------------
+ for(int i = 0; i < 360; i += 360/sides)
+ {
+ rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); //Bottom Left
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); //Bottom Right
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); //Top Right
+
+ rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop); //Top Left
+ rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); //Bottom Left
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); //Top Right
+ }
+
+ // Draw Cap --------------------------------------------------------------------------------------
+ for(int i = 0; i < 360; i += 360/sides)
+ {
+ rlVertex3f(0, height, 0);
+ rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop);
+ }
}
- rlEnd();
- }
- else // Draw cylinder
- {
-
- // TODO: Review drawing to use RL_TRIANGLES
-
- // Draw cylinder top (pointed cap)
- rlBegin(GL_TRIANGLE_FAN);
- rlColor4ub(color.r, color.g, color.b, color.a);
- rlVertex3f(c.x, c.y + height, c.z);
- for (int i = slices; i >= 0; i--)
+ else
{
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusTop);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
- rlVertex3f(p.x, p.y, p.z);
+ // Draw Cone -------------------------------------------------------------------------------------
+ for(int i = 0; i < 360; i += 360/sides)
+ {
+ rlVertex3f(0, height, 0);
+ rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
+ }
}
- rlEnd();
-
- // Draw cylinder sides
- rlBegin(GL_TRIANGLE_STRIP);
- rlColor4ub(color.r, color.g, color.b, color.a);
- for (int i = slices; i >= 0; i--)
+
+ // Draw Base -----------------------------------------------------------------------------------------
+ for(int i = 0; i < 360; i += 360/sides)
{
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusTop);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
- rlVertex3f(p.x, p.y, p.z);
-
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
- rlVertex3f(p.x, p.y, p.z);
+ rlVertex3f(0, 0, 0);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
+ rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
}
- rlEnd();
+ rlEnd();
+ rlPopMatrix();
+}
+
+// Draw a wired cylinder
+// NOTE: It could be also used for pyramid and cone
+void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color)
+{
+ if(sides < 3) sides = 3;
+
+ rlPushMatrix();
+ rlTranslatef(position.x, position.y, position.z);
- // Draw cylinder bottom
- rlBegin(GL_TRIANGLE_FAN);
+ rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
- rlVertex3f(c.x, c.y, c.z);
- for (int i = slices; i >= 0; i--)
+
+ for(int i = 0; i < 360; i += 360/sides)
{
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
- rlVertex3f(p.x, p.y, p.z);
+ rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
+
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop);
+
+ rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop);
+ rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop);
+
+ rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop);
+ rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
}
rlEnd();
- }
-}
-
-// Draw a cylinder/cone wires
-void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color)
-{
- // TODO: Draw sphere using RL_LINES!
-
- //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- DrawCylinder(position, radiusTop, radiusBottom, height, slices, color);
- //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ rlPopMatrix();
}
// Draw a plane
+// TODO: Test this function
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
{
- // TODO: Review vertex translate/rotate/scale mechanism
-
// NOTE: Plane is always created on XZ ground and then rotated
rlPushMatrix();
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
@@ -353,7 +454,7 @@ void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
rlRotatef(rotation.z, 0, 0, 1);
rlScalef(size.x, 1.0f, size.y);
- rlBegin(GL_QUADS);
+ rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
rlNormal3f(0.0f, 1.0f, 0.0f);
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(-0.5f, 0.0f, -0.5f);
@@ -365,6 +466,7 @@ void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
}
// Draw a plane with divisions
+// TODO: Test this function
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color)
{
float quadWidth = size.x / slicesX;
@@ -373,8 +475,6 @@ void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX,
float texPieceW = 1 / size.x;
float texPieceH = 1 / size.y;
- // TODO: Review vertex translate/rotate/scale mechanism
-
// NOTE: Plane is always created on XZ ground and then rotated
rlPushMatrix();
rlTranslatef(-size.x / 2, 0.0f, -size.y / 2);
@@ -444,66 +544,116 @@ void DrawGrid(int slices, float spacing)
rlEnd();
}
-// Draw gizmo (with or without orbits)
-void DrawGizmo(Vector3 position, bool orbits)
+// Draw gizmo
+void DrawGizmo(Vector3 position)
{
// NOTE: RGB = XYZ
float lenght = 1.0f;
- float radius = 1.0f;
-
- //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
- //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
-
- // GL_LINE_SMOOTH is very poorly supported on desktop GL.
- // A lot of drivers ignore it, so most people avoid using...
-
+
rlPushMatrix();
rlTranslatef(position.x, position.y, position.z);
- //glRotatef(rotation, 0, 1, 0);
+ //rlRotatef(rotation, 0, 1, 0);
rlScalef(lenght, lenght, lenght);
- rlBegin(GL_LINES);
- rlColor3f(1.0f, 0.0f, 0.0f);
- rlVertex3f(0.0f, 0.0f, 0.0f);
- rlVertex3f(1.0f, 0.0f, 0.0f);
+ rlBegin(RL_LINES);
+ rlColor3f(1.0f, 0.0f, 0.0f); rlVertex3f(0.0f, 0.0f, 0.0f);
+ rlColor3f(1.0f, 0.0f, 0.0f); rlVertex3f(1.0f, 0.0f, 0.0f);
- rlColor3f(0.0f, 1.0f, 0.0f);
- rlVertex3f(0.0f, 0.0f, 0.0f);
- rlVertex3f(0.0f, 1.0f, 0.0f);
+ rlColor3f(0.0f, 1.0f, 0.0f); rlVertex3f(0.0f, 0.0f, 0.0f);
+ rlColor3f(0.0f, 1.0f, 0.0f); rlVertex3f(0.0f, 1.0f, 0.0f);
- rlColor3f(0.0f, 0.0f, 1.0f);
- rlVertex3f(0.0f, 0.0f, 0.0f);
- rlVertex3f(0.0f, 0.0f, 1.0f);
- rlEnd();
+ rlColor3f(0.0f, 0.0f, 1.0f); rlVertex3f(0.0f, 0.0f, 0.0f);
+ rlColor3f(0.0f, 0.0f, 1.0f); rlVertex3f(0.0f, 0.0f, 1.0f);
+ rlEnd();
+ rlPopMatrix();
+}
+
+void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale, bool orbits)
+{
+ // NOTE: RGB = XYZ
+ rlPushMatrix();
+ rlTranslatef(position.x, position.y, position.z);
+ rlScalef(scale, scale, scale);
- if (orbits)
- {
- rlBegin(GL_LINE_LOOP);
- rlColor4f(1.0f, 0.0f, 0.0f, 0.4f);
- for (int i=0; i < 360; i++) rlVertex3f(sin(DEG2RAD*i) * radius, 0, cos(DEG2RAD*i) * radius);
- rlEnd();
-
- rlBegin(GL_LINE_LOOP);
- rlColor4f(0.0f, 1.0f, 0.0f, 0.4f);
- for (int i=0; i < 360; i++) rlVertex3f(sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius, 0);
- rlEnd();
-
- rlBegin(GL_LINE_LOOP);
- rlColor4f(0.0f, 0.0f, 1.0f, 0.4f);
- for (int i=0; i < 360; i++) rlVertex3f(0, sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius);
- rlEnd();
- }
+ if(rotation.x) rlRotatef(rotation.x, 1, 0, 0);
+ if(rotation.y) rlRotatef(rotation.y, 0, 1, 0);
+ if(rotation.z) rlRotatef(rotation.z, 0, 0, 1);
+ rlBegin(RL_LINES);
+ // X Axis
+ rlColor4ub(200, 0, 0, 255); // RED
+ rlVertex3f(position.x, position.y, position.z);
+ rlVertex3f(position.x + 1, position.y, position.z);
+
+ // ArrowX
+ rlVertex3f(position.x + 1.1, position.y, position.z);
+ rlVertex3f(position.x + .9, position.y, position.z + .1);
+
+ rlVertex3f(position.x + 1.1, position.y, position.z);
+ rlVertex3f(position.x + .9, position.y, position.z - .1);
+
+ // Y Axis
+ rlColor4ub(0, 200, 0, 255); // GREEN
+ rlVertex3f(position.x, position.y, position.z);
+ rlVertex3f(position.x, position.y + 1, position.z);
+
+ // ArrowY
+ rlVertex3f(position.x, position.y + 1.1, position.z);
+ rlVertex3f(position.x + .1, position.y + .9, position.z);
+
+ rlVertex3f(position.x, position.y + 1.1, position.z);
+ rlVertex3f(position.x - .1, position.y + .9, position.z);
+
+ // Z Axis
+ rlColor4ub(0, 0, 200, 255); // BLUE
+ rlVertex3f(position.x, position.y, position.z);
+ rlVertex3f(position.x, position.y, position.z - 1);
+
+ // ArrowZ
+ rlVertex3f(position.x, position.y, position.z - 1.1);
+ rlVertex3f(position.x + .1, position.y, position.z - .9);
+
+ rlVertex3f(position.x, position.y, position.z - 1.1);
+ rlVertex3f(position.x - .1, position.y, position.z - .9);
+
+ // Extra
+ if(orbits)
+ {
+ int n = 3;
+
+ // X Axis
+ rlColor4ub(200, 0, 0, 255); // RED
+ for (int i=0; i < 360; i++)
+ {
+ rlVertex3f(0, position.x + sin(DEG2RAD*i) * scale/n, position.y + cos(DEG2RAD*i) * scale/n);
+ rlVertex3f(0,position.x + sin(DEG2RAD*(i+1)) * scale/n, position.y + cos(DEG2RAD*(i+1)) * scale/n);
+ }
+
+ // Y Axis
+ rlColor4ub(0, 200, 0, 255); // GREEN
+ for (int i=0; i < 360; i++)
+ {
+ rlVertex3f(position.x + sin(DEG2RAD*i) * scale/n, 0, position.y + cos(DEG2RAD*i) * scale/n);
+ rlVertex3f(position.x + sin(DEG2RAD*(i+1)) * scale/n, 0, position.y + cos(DEG2RAD*(i+1)) * scale/n);
+ }
+
+ // Z Axis
+ rlColor4ub(0, 0, 200, 255); // BLUE
+ for (int i=0; i < 360; i++)
+ {
+ rlVertex3f(position.x + sin(DEG2RAD*i) * scale/n, position.y + cos(DEG2RAD*i) * scale/n, 0);
+ rlVertex3f(position.x + sin(DEG2RAD*(i+1)) * scale/n, position.y + cos(DEG2RAD*(i+1)) * scale/n, 0);
+ }
+ }
+ rlEnd();
rlPopMatrix();
-
- //glDisable(GL_LINE_SMOOTH);
}
// Load a 3d model (.OBJ)
// TODO: Add comments explaining this function process
Model LoadModel(const char *fileName)
{
- struct Model model;
+ VertexData vData;
char dataType;
char comments[200];
@@ -617,17 +767,19 @@ Model LoadModel(const char *fileName)
Vector3 midNormals[numNormals];
Vector2 midTexCoords[numTexCoords];
- model.numVertices = numTriangles*3;
-
- model.vertices = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
- model.normals = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
- model.texcoords = (Vector2 *)malloc(model.numVertices * sizeof(Vector2));
+ vData.numVertices = numTriangles*3;
+
+ vData.vertices = (float *)malloc(vData.numVertices * 3 * sizeof(float));
+ vData.texcoords = (float *)malloc(vData.numVertices * 2 * sizeof(float));
+ vData.normals = (float *)malloc(vData.numVertices * 3 * sizeof(float));
int countVertex = 0;
int countNormals = 0;
int countTexCoords = 0;
- int countMaxVertex = 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);
@@ -671,31 +823,58 @@ Model LoadModel(const char *fileName)
} 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);
- model.vertices[countMaxVertex] = midVertices[vNum-1];
- model.normals[countMaxVertex] = midNormals[vnNum-1];
- model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
- model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
- countMaxVertex++;
-
+ 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);
- model.vertices[countMaxVertex] = midVertices[vNum-1];
- model.normals[countMaxVertex] = midNormals[vnNum-1];
- model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
- model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
- countMaxVertex++;
+ 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);
- model.vertices[countMaxVertex] = midVertices[vNum-1];
- model.normals[countMaxVertex] = midNormals[vnNum-1];
- model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
- model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
- countMaxVertex++;
+ 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;
} break;
default: break;
}
@@ -703,10 +882,19 @@ Model LoadModel(const char *fileName)
fclose(objFile);
-#ifdef USE_OPENGL_33
-
- // TODO: Use loaded data to generate VAO
+ // NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct
+
+ Model model;
+#ifdef USE_OPENGL_11
+ model.data = vData; // model data is vertex data
+#else
+ model.vaoId = rlglLoadModel(vData); // Use loaded data to generate VAO
+
+ // Now that vertex data is uploaded to GPU, we can free arrays
+ free(vData.vertices);
+ free(vData.texcoords);
+ free(vData.normals);
#endif
return model;
@@ -715,8 +903,8 @@ Model LoadModel(const char *fileName)
// Load a heightmap image as a 3d model
Model LoadHeightmap(Image heightmap, float maxHeight)
{
- Model model;
-
+ VertexData vData;
+
int mapX = heightmap.width;
int mapZ = heightmap.height;
@@ -724,13 +912,16 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
// TODO: Consider resolution when generating model data?
int numTriangles = (mapX-1)*(mapZ-1)*2; // One quad every four pixels
- model.numVertices = numTriangles*3;
+ vData.numVertices = numTriangles*3;
- model.vertices = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
- model.normals = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
- model.texcoords = (Vector2 *)malloc(model.numVertices * sizeof(Vector2));
+ vData.vertices = (float *)malloc(vData.numVertices * 3 * sizeof(float));
+ vData.normals = (float *)malloc(vData.numVertices * 3 * sizeof(float));
+ vData.texcoords = (float *)malloc(vData.numVertices * 2 * sizeof(float));
+
+ 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 vCounter = 0;
int trisCounter = 0;
float scaleFactor = maxHeight/255; // TODO: Review scaleFactor calculation
@@ -743,62 +934,82 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
//----------------------------------------------------------
// one triangle - 3 vertex
- model.vertices[vCounter].x = x;
- model.vertices[vCounter].y = GetHeightValue(heightmap.pixels[x + z*mapX])*scaleFactor;
- model.vertices[vCounter].z = z;
+ vData.vertices[vCounter] = x;
+ vData.vertices[vCounter + 1] = GetHeightValue(heightmap.pixels[x + z*mapX])*scaleFactor;
+ vData.vertices[vCounter + 2] = z;
- model.vertices[vCounter+1].x = x;
- model.vertices[vCounter+1].y = GetHeightValue(heightmap.pixels[x + (z+1)*mapX])*scaleFactor;
- model.vertices[vCounter+1].z = z+1;
+ vData.vertices[vCounter + 3] = x;
+ vData.vertices[vCounter + 4] = GetHeightValue(heightmap.pixels[x + (z+1)*mapX])*scaleFactor;
+ vData.vertices[vCounter + 5] = z+1;
- model.vertices[vCounter+2].x = x+1;
- model.vertices[vCounter+2].y = GetHeightValue(heightmap.pixels[(x+1) + z*mapX])*scaleFactor;
- model.vertices[vCounter+2].z = z;
+ vData.vertices[vCounter + 6] = x+1;
+ vData.vertices[vCounter + 7] = GetHeightValue(heightmap.pixels[(x+1) + z*mapX])*scaleFactor;
+ vData.vertices[vCounter + 8] = z;
// another triangle - 3 vertex
- model.vertices[vCounter+3] = model.vertices[vCounter+2];
- model.vertices[vCounter+4] = model.vertices[vCounter+1];
+ vData.vertices[vCounter + 9] = vData.vertices[vCounter + 6];
+ vData.vertices[vCounter + 10] = vData.vertices[vCounter + 7];
+ vData.vertices[vCounter + 11] = vData.vertices[vCounter + 8];
- model.vertices[vCounter+5].x = x+1;
- model.vertices[vCounter+5].y = GetHeightValue(heightmap.pixels[(x+1) + (z+1)*mapX])*scaleFactor;
- model.vertices[vCounter+5].z = z+1;
+ vData.vertices[vCounter + 12] = vData.vertices[vCounter + 3];
+ vData.vertices[vCounter + 13] = vData.vertices[vCounter + 4];
+ vData.vertices[vCounter + 14] = vData.vertices[vCounter + 5];
+
+ vData.vertices[vCounter + 15] = x+1;
+ vData.vertices[vCounter + 16] = GetHeightValue(heightmap.pixels[(x+1) + (z+1)*mapX])*scaleFactor;
+ vData.vertices[vCounter + 17] = z+1;
+ vCounter += 18; // 6 vertex, 18 floats
// Fill texcoords array with data
//--------------------------------------------------------------
- model.texcoords[vCounter].x = (float)x / (mapX-1);
- model.texcoords[vCounter].y = (float)z / (mapZ-1);
+ vData.texcoords[tcCounter] = (float)x / (mapX-1);
+ vData.texcoords[tcCounter + 1] = (float)z / (mapZ-1);
+
+ vData.texcoords[tcCounter + 2] = (float)x / (mapX-1);
+ vData.texcoords[tcCounter + 3] = (float)(z+1) / (mapZ-1);
- model.texcoords[vCounter+1].x = (float)x / (mapX-1);
- model.texcoords[vCounter+1].y = (float)(z+1) / (mapZ-1);
+ vData.texcoords[tcCounter + 4] = (float)(x+1) / (mapX-1);
+ vData.texcoords[tcCounter + 5] = (float)z / (mapZ-1);
- model.texcoords[vCounter+2].x = (float)(x+1) / (mapX-1);
- model.texcoords[vCounter+2].y = (float)z / (mapZ-1);
+ vData.texcoords[tcCounter + 6] = vData.texcoords[tcCounter + 4];
+ vData.texcoords[tcCounter + 7] = vData.texcoords[tcCounter + 5];
- model.texcoords[vCounter+3] = model.texcoords[vCounter+2];
- model.texcoords[vCounter+4] = model.texcoords[vCounter+1];
+ vData.texcoords[tcCounter + 8] = vData.texcoords[tcCounter + 2];
+ vData.texcoords[tcCounter + 9] = vData.texcoords[tcCounter + 1];
- model.texcoords[vCounter+5].x = (float)(x+1) / (mapX-1);
- model.texcoords[vCounter+5].y = (float)(z+1) / (mapZ-1);
+ vData.texcoords[tcCounter + 10] = (float)(x+1) / (mapX-1);
+ vData.texcoords[tcCounter + 11] = (float)(z+1) / (mapZ-1);
+ tcCounter += 12; // 6 texcoords, 12 floats
// Fill normals array with data
//--------------------------------------------------------------
// TODO: Review normals calculation
- model.normals[vCounter] = (Vector3){ 0.0f, 1.0f, 0.0f };
- model.normals[vCounter+1] = (Vector3){ 0.0f, 1.0f, 0.0f };
- model.normals[vCounter+2] = (Vector3){ 0.0f, 1.0f, 0.0f };
- model.normals[vCounter+3] = (Vector3){ 0.0f, 1.0f, 0.0f };
- model.normals[vCounter+4] = (Vector3){ 0.0f, 1.0f, 0.0f };
- model.normals[vCounter+5] = (Vector3){ 0.0f, 1.0f, 0.0f };
-
- vCounter += 6;
+ for (int i = 0; i < 18; i += 3)
+ {
+ vData.normals[nCounter + i] = 0.0f;
+ vData.normals[nCounter + i + 1] = 1.0f;
+ vData.normals[nCounter + i + 2] = 0.0f;
+ }
+
+ nCounter += 18; // 6 vertex, 18 floats
+
trisCounter += 2;
}
}
-#ifdef USE_OPENGL_33
-
- // TODO: Use loaded data to generate VAO
+ // NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct
+
+ Model model;
+
+#ifdef USE_OPENGL_11
+ model.data = vData; // model data is vertex data
+#else
+ model.vaoId = rlglLoadModel(vData); // Use loaded data to generate VAO
+ // Now that vertex data is uploaded to GPU, we can free arrays
+ free(vData.vertices);
+ free(vData.texcoords);
+ free(vData.normals);
#endif
return model;
@@ -807,62 +1018,21 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
// Unload 3d model from memory
void UnloadModel(Model model)
{
- free(model.vertices);
- free(model.texcoords);
- free(model.normals);
+#ifdef USE_OPENGL_11
+ free(model.data.vertices);
+ free(model.data.texcoords);
+ free(model.data.normals);
+#endif
+
+#ifdef USE_OPENGL_33
+ rlDeleteVertexArrays(model.vaoId);
+#endif
}
// Draw a model
void DrawModel(Model model, Vector3 position, float scale, Color color)
{
- // NOTE: For models we use Vertex Arrays (OpenGL 1.1)
- //static int rotation = 0;
-
- // NOTE: Add OpenGL 3.3+ VAOs-based drawing! --> Move this stuff to rlgl?
-
- glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
- glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
- glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
-
- glVertexPointer(3, GL_FLOAT, 0, model.vertices); // Pointer to vertex coords array
- glTexCoordPointer(2, GL_FLOAT, 0, model.texcoords); // Pointer to texture coords array
- glNormalPointer(GL_FLOAT, 0, model.normals); // Pointer to normals array
- //glColorPointer(4, GL_UNSIGNED_BYTE, 0, model.colors); // Pointer to colors array (NOT USED)
-
- rlPushMatrix();
- rlTranslatef(position.x, position.y, position.z);
- //glRotatef(rotation * GetFrameTime(), 0, 1, 0);
- rlScalef(scale, scale, scale);
-
- rlColor4ub(color.r, color.g, color.b, color.a);
-
- glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
- rlPopMatrix();
-
- glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
- glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
- glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
-
- //rotation += 10;
-
-// Model drawing in OpenGL 3.3+, transform is passed to shader
-/*
- glUseProgram(shaderProgram); // Use our shader
-
- Matrix modelview = MatrixMultiply(model.transform, view);
-
- glUniformMatrix4fv(projectionMatrixLoc, 1, false, GetMatrixVector(projection));
- glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelview));
- glUniform1i(textureLoc, 0);
-
- glBindVertexArray(model.vaoId);
- glBindTexture(GL_TEXTURE_2D, model.texId);
-
- glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
-
- glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
- glBindVertexArray(0); // Unbind VAO
-*/
+ rlglDrawModel(model, false);
}
// Draw a textured model
@@ -878,11 +1048,7 @@ void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale,
// Draw a model wires
void DrawModelWires(Model model, Vector3 position, float scale, Color color)
{
- // TODO: Draw model using RL_LINES... or look for a way to deal with polygon mode!
-
- //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- DrawModel(model, position, scale, color);
- //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ rlglDrawModel(model, true);
}
// Draw a billboard
diff --git a/src/raylib.h b/src/raylib.h
index 4534c5ec..450d2e6f 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -355,15 +355,17 @@ const char *FormatText(const char *text, ...);
void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
+void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
-void DrawSphereWires(Vector3 centerPos, float radius, Color color); // Draw sphere wires
+void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
-void DrawGizmo(Vector3 position, bool orbits); // Draw gizmo (with or without orbits)
+void DrawGizmo(Vector3 position); // Draw simple gizmo
+void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale, bool orbits); // Draw gizmo with extended parameters
//DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------
diff --git a/src/rlgl.c b/src/rlgl.c
index 63ed9ec4..e25e72be 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -49,9 +49,9 @@
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#define MATRIX_STACK_SIZE 16 // TODO: REVIEW: Matrix stack required?
+#define MATRIX_STACK_SIZE 16 // Matrix stack max size
#define MAX_DRAWS_BY_TEXTURE 256 // Draws are organized by texture changes
-#define TEMP_VERTEX_BUFFER_SIZE 1024 // Temporal Vertex Buffer (required for post-transformations)
+#define TEMP_VERTEX_BUFFER_SIZE 1024 // Temporal Vertex Buffer (required for vertex-transformations)
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -67,7 +67,7 @@ typedef struct {
float *vertices; // 3 components per vertex
float *colors; // 4 components per vertex
} VertexPositionColorBuffer;
-
+/*
typedef struct {
int vCounter;
int tcCounter;
@@ -76,7 +76,17 @@ typedef struct {
float *texcoords; // 2 components per vertex
float *colors; // 4 components per vertex
} VertexPositionColorTextureBuffer;
-
+*/
+/*
+typedef struct {
+ int vCounter;
+ int tcCounter;
+ int nCounter;
+ float *vertices; // 3 components per vertex
+ float *texcoords; // 2 components per vertex
+ float *normals; // 3 components per vertex
+} VertexPositionTextureNormalBuffer;
+*/
typedef struct {
int vCounter;
int tcCounter;
@@ -108,8 +118,8 @@ static int currentMatrixMode;
static DrawMode currentDrawMode;
// Vertex arrays for lines, triangles and quads
-static VertexPositionColorBuffer lines;
-static VertexPositionColorTextureBuffer triangles;
+static VertexPositionColorBuffer lines; // No texture support
+static VertexPositionColorBuffer triangles; // No texture support
static VertexPositionColorTextureIndexBuffer quads;
// Vetex-Fragment Shader Program ID
@@ -614,6 +624,14 @@ void rlDeleteTextures(unsigned int id)
glDeleteTextures(1, &id);
}
+// Unload vertex data from GPU memory
+void rlDeleteVertexArrays(unsigned int id)
+{
+#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
+ glDeleteVertexArrays(1, &id);
+#endif
+}
+
// Clear color buffer with color
void rlClearColor(byte r, byte g, byte b, byte a)
{
@@ -655,10 +673,11 @@ void rlglInit()
if (glewIsSupported("GL_VERSION_3_3")) printf("OpenGL 3.3 initialized\n");
/*
+ // TODO: GLEW is a big library that loads ALL extensions, maybe using glad we can only load required ones...
if (!gladLoadGL())
{
- printf("Something went wrong!\n");
- exit(-1);
+ fprintf(stderr, printf("Failed to initialize glad.\n");
+ exit(1);
}
*/
// Set default draw mode
@@ -694,7 +713,7 @@ void rlglInit()
printf("Vendor: %s\n", glGetString(GL_VENDOR));
printf("Renderer: %s\n", glGetString(GL_RENDERER));
printf("Version: %s\n", glGetString(GL_VERSION));
- printf("GLSL: %s\n\n", glGetString(0x8B8C)); // GL_SHADING_LANGUAGE_VERSION
+ printf("GLSL: %s\n\n", glGetString(0x8B8C)); //GL_SHADING_LANGUAGE_VERSION
InitializeBuffers(); // Init vertex arrays
InitializeVAOs(); // Init VBO and VAO
@@ -707,7 +726,7 @@ void rlglInit()
// Create default white texture for plain colors (required by shader)
unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes)
- whiteTexture = rlglTexture(1, 1, pixels);
+ whiteTexture = rlglLoadTexture(1, 1, pixels);
// Init draw calls tracking system
draws = (DrawCall *)malloc(sizeof(DrawCall)*MAX_DRAWS_BY_TEXTURE);
@@ -794,8 +813,12 @@ void rlglDraw()
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)
@@ -830,8 +853,6 @@ void rlglDraw()
glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid*) (sizeof(GLuint) * indicesOffset));
indicesOffset += draws[i].vCount/4*6;
-
- //printf("-------Next vertex offset: %i\n", indicesOffset/6*4);
}
}
@@ -849,7 +870,7 @@ void rlglDraw()
lines.cCounter = 0;
triangles.vCounter = 0;
- triangles.vCounter = 0;
+ triangles.cCounter = 0;
quads.vCounter = 0;
quads.tcCounter = 0;
@@ -861,6 +882,58 @@ void rlglDraw()
#endif
}
+void rlglDrawModel(Model model, bool wires)
+{
+ if (wires) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+#ifdef USE_OPENGL_11
+ // NOTE: For models we use Vertex Arrays (OpenGL 1.1)
+ glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
+ glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
+
+ glVertexPointer(3, GL_FLOAT, 0, model.vertices); // Pointer to vertex coords array
+ glTexCoordPointer(2, GL_FLOAT, 0, model.texcoords); // Pointer to texture coords array
+ glNormalPointer(GL_FLOAT, 0, model.normals); // Pointer to normals array
+ //glColorPointer(4, GL_UNSIGNED_BYTE, 0, model.colors); // Pointer to colors array (NOT USED)
+
+ rlPushMatrix();
+ rlTranslatef(position.x, position.y, position.z);
+ //glRotatef(rotation * GetFrameTime(), 0, 1, 0);
+ rlScalef(scale, scale, scale);
+
+ rlColor4ub(color.r, color.g, color.b, color.a);
+
+ glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
+ rlPopMatrix();
+
+ glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
+ glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
+#endif
+
+#ifdef USE_OPENGL_33
+ glUseProgram(shaderProgram); // Use our shader
+
+ Matrix modelview2 = MatrixMultiply(model.transform, modelview);
+
+ // NOTE: Drawing in OpenGL 3.3+, transform is passed to shader
+ glUniformMatrix4fv(projectionMatrixLoc, 1, false, GetMatrixVector(projection));
+ glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelview2));
+ glUniform1i(textureLoc, 0);
+
+ glBindVertexArray(model.vaoId);
+ //glBindTexture(GL_TEXTURE_2D, model.textureId);
+
+ glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
+
+ //glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
+ glBindVertexArray(0); // Unbind VAO
+#endif
+
+ if (wires) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+}
+
#endif
// Initialize Graphics Device (OpenGL stuff)
@@ -909,7 +982,7 @@ void rlglInitGraphicsDevice(int fbWidth, int fbHeight)
// Convert image data to OpenGL texture (returns OpenGL valid Id)
// NOTE: Image is not unloaded, it should be done manually...
-unsigned int rlglTexture(int width, int height, unsigned char *pixels)
+unsigned int rlglLoadTexture(int width, int height, unsigned char *pixels)
{
glBindTexture(GL_TEXTURE_2D,0); // Free any old binding
@@ -926,7 +999,7 @@ unsigned int rlglTexture(int width, int height, unsigned char *pixels)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
#ifdef USE_OPENGL_33
- // Trilinear filtering!
+ // Trilinear filtering
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate use of mipmaps (must be available)
//glGenerateMipmap(GL_TEXTURE_2D); // OpenGL 3.3!
@@ -947,6 +1020,39 @@ unsigned int rlglTexture(int width, int height, unsigned char *pixels)
return id;
}
+#ifdef USE_OPENGL_33
+unsigned int rlglLoadModel(VertexData data)
+{
+ GLuint vaoModel; // Vertex Array Objects (VAO)
+ GLuint vertexBuffer[3]; // Vertex Buffer Objects (VBO)
+
+ // Initialize Quads VAO (Buffer A)
+ glGenVertexArrays(1, &vaoModel);
+ glBindVertexArray(vaoModel);
+
+ // Create buffers for our vertex data (positions, texcoords, normals)
+ glGenBuffers(3, vertexBuffer);
+
+ // Enable vertex attributes
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*data.numVertices, data.vertices, GL_STATIC_DRAW);
+ glEnableVertexAttribArray(vertexLoc);
+ glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*data.numVertices, data.texcoords, GL_STATIC_DRAW);
+ glEnableVertexAttribArray(texcoordLoc);
+ glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[2]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*data.numVertices, data.normals, GL_STATIC_DRAW);
+ //glEnableVertexAttribArray(normalLoc);
+ //glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0);
+
+ return vaoModel;
+}
+#endif
+
// Read screen pixel data (color buffer)
unsigned char *rlglReadScreenPixels(int width, int height)
{
@@ -1303,11 +1409,13 @@ static void UpdateBuffers()
// Triangles - vertex positions buffer
glBindBuffer(GL_ARRAY_BUFFER, trianglesBuffer[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*3*MAX_TRIANGLES_BATCH, triangles.vertices, GL_DYNAMIC_DRAW);
-
+ //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*3*MAX_TRIANGLES_BATCH, triangles.vertices, GL_DYNAMIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*triangles.vCounter, triangles.vertices);
+
// 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);
+ //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);
//--------------------------------------------------------------
@@ -1355,6 +1463,12 @@ static void UpdateBuffers()
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*quads.vCounter, quads.colors);
}
+
+ // Another option would be using buffer mapping...
+ //triangles.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
+ // Now we can modify vertices
+ //glUnmapBuffer(GL_ARRAY_BUFFER);
+
//--------------------------------------------------------------
// Unbind the current VAO
diff --git a/src/rlgl.h b/src/rlgl.h
index b4033050..174310dd 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -29,9 +29,15 @@
#ifndef RLGL_H
#define RLGL_H
+//#define RLGL_STANDALONE // NOTE: To use rlgl as standalone lib, just uncomment this line
+
+#ifndef RLGL_STANDALONE
+ #include "raylib.h" // Required for typedef: Model
+#endif
+
// Select desired OpenGL version
-//#define USE_OPENGL_11
-#define USE_OPENGL_33
+#define USE_OPENGL_11
+//#define USE_OPENGL_33
//#define USE_OPENGL_ES2
//----------------------------------------------------------------------------------
@@ -50,6 +56,29 @@ typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode;
typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
+#ifdef RLGL_STANDALONE
+ typedef struct Model Model;
+#endif
+
+typedef struct {
+ int numVertices;
+ float *vertices; // 3 components per vertex
+ float *texcoords; // 2 components per vertex
+ float *normals; // 3 components per vertex
+} VertexData;
+
+#ifdef USE_OPENGL_11
+struct Model {
+ VertexData data;
+};
+#else
+struct Model {
+ unsigned int vaoId;
+ Matrix transform;
+ int numVertices;
+};
+#endif
+
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
@@ -88,7 +117,8 @@ void rlColor4f(float x, float y, float z, float w); // Define one vertex (color)
//------------------------------------------------------------------------------------
void rlEnableTexture(unsigned int id); // Enable texture usage
void rlDisableTexture(); // Disable texture usage
-void rlDeleteTextures(unsigned int id); // Delete OpenGL texture
+void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
+void rlDeleteVertexArrays(unsigned int id); // Unload vertex data from GPU memory
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
void rlClearScreenBuffers(); // Clear used screen buffers (color and depth)
@@ -96,13 +126,15 @@ void rlClearScreenBuffers(); // Clear used screen buffers (color
// Functions Declaration - rlgl functionality
//------------------------------------------------------------------------------------
#ifdef USE_OPENGL_33
-void rlglInit(); // Initialize rlgl (shaders, VAO, VBO...)
-void rlglClose(); // De-init rlgl
-void rlglDraw(); // Draw VAOs
+void rlglInit(); // Initialize rlgl (shaders, VAO, VBO...)
+void rlglClose(); // De-init rlgl
+void rlglDraw(); // Draw VAOs
+unsigned int rlglLoadModel(VertexData data);
#endif
+void rlglDrawModel(Model model, bool wires); // Draw model
void rlglInitGraphicsDevice(int fbWidth, int fbHeight); // Initialize Graphics Device (OpenGL stuff)
-unsigned int rlglTexture(int width, int height, unsigned char *pixels); // Create OpenGL texture
+unsigned int rlglLoadTexture(int width, int height, unsigned char *pixels); // Load in GPU OpenGL texture
byte *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
#ifdef USE_OPENGL_33
diff --git a/src/shapes.c b/src/shapes.c
index 838a9efa..42496351 100644
--- a/src/shapes.c
+++ b/src/shapes.c
@@ -62,7 +62,7 @@ void DrawPixel(int posX, int posY, Color color)
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(posX, posY);
rlVertex2i(posX + 1, posY + 1);
- rlEnd();
+ rlEnd();
}
// Draw a pixel (Vector version)
@@ -96,7 +96,6 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
}
// Draw a color-filled circle
-// TODO: Review, on some GPUs is drawn with a weird transparency (GL_POLYGON_SMOOTH issue?)
void DrawCircle(int centerX, int centerY, float radius, Color color)
{
DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color);
@@ -107,13 +106,13 @@ void DrawCircle(int centerX, int centerY, float radius, Color color)
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
{
rlBegin(RL_TRIANGLES);
- for (int i=0; i <= 360; i += 2) //i++ --> Step = 1.0 pixels
+ for (int i=0; i < 360; i += 2)
{
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
rlVertex2i(centerX, centerY);
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
- rlVertex2f(centerX + sin(DEG2RAD*(i+1)) * radius, centerY + cos(DEG2RAD*(i+1)) * radius);
+ rlVertex2f(centerX + sin(DEG2RAD*(i+2)) * radius, centerY + cos(DEG2RAD*(i+2)) * radius);
}
rlEnd();
}
@@ -127,7 +126,7 @@ void DrawCircleV(Vector2 center, float radius, Color color)
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(center.x, center.y);
rlVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
- rlVertex2f(center.x + sin(DEG2RAD*(i+1)) * radius, center.y + cos(DEG2RAD*(i+1)) * radius);
+ rlVertex2f(center.x + sin(DEG2RAD*(i+2)) * radius, center.y + cos(DEG2RAD*(i+2)) * radius);
}
rlEnd();
}
@@ -135,9 +134,6 @@ void DrawCircleV(Vector2 center, float radius, Color color)
// Draw circle outline
void DrawCircleLines(int centerX, int centerY, float radius, Color color)
{
- //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
- //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
-
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
@@ -148,10 +144,6 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
rlVertex2f(centerX + sin(DEG2RAD*(i+1)) * radius, centerY + cos(DEG2RAD*(i+1)) * radius);
}
rlEnd();
-
- //glDisable(GL_LINE_SMOOTH);
-
- // TODO: Draw all lines with line smooth??? --> Do it before drawing lines VAO
}
// Draw a color-filled rectangle
@@ -255,16 +247,17 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
if (sides < 3) sides = 3;
rlPushMatrix();
-
- rlRotatef(rotation, 0, 0, 1); // TODO: compute vertex rotation manually!
+ rlTranslatef(center.x, center.y, 0.0);
+ rlRotatef(rotation, 0, 0, 1);
rlBegin(RL_TRIANGLES);
- for (int i=0; i < 360; i += 2)
+ for (int i=0; i < 360; i += 360/sides)
{
rlColor4ub(color.r, color.g, color.b, color.a);
- rlVertex2i(center.x, center.y);
- rlVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
- rlVertex2f(center.x + sin(DEG2RAD*(i+1)) * radius, center.y + cos(DEG2RAD*(i+1)) * radius);
+
+ rlVertex2i(0, 0);
+ rlVertex2f(sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius);
+ rlVertex2f(sin(DEG2RAD*(i+360/sides)) * radius, cos(DEG2RAD*(i+360/sides)) * radius);
}
rlEnd();
rlPopMatrix();
diff --git a/src/text.c b/src/text.c
index b897f1f3..2d75a6d9 100644
--- a/src/text.c
+++ b/src/text.c
@@ -313,7 +313,6 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
rlEnableTexture(spriteFont.texture.glId);
- // Optimized to use one draw call per string
rlBegin(RL_QUADS);
for(int i = 0; i < length; i++)
{
diff --git a/src/textures.c b/src/textures.c
index f8402b0c..75300eac 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -273,31 +273,30 @@ void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float sc
{
rlEnableTexture(texture.glId);
- // TODO: Apply rotation to vertex! --> rotate from origin CW (0, 0)
- // TODO: Compute vertex scaling!
-
// NOTE: Rotation is applied before translation and scaling, even being called in inverse order...
- // NOTE: Rotation point is upper-left corner
- //rlTranslatef(position.x, position.y, 0);
- //rlScalef(scale, scale, 1.0f);
- //rlRotatef(rotation, 0, 0, 1);
-
- rlBegin(RL_QUADS);
- rlColor4ub(tint.r, tint.g, tint.b, tint.a);
- rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
-
- rlTexCoord2f(0.0f, 0.0f);
- rlVertex2f(position.x, position.y); // Bottom-left corner for texture and quad
-
- rlTexCoord2f(0.0f, 1.0f);
- rlVertex2f(position.x, position.y + texture.height); // Bottom-right corner for texture and quad
-
- rlTexCoord2f(1.0f, 1.0f);
- rlVertex2f(position.x + texture.width, position.y + texture.height); // Top-right corner for texture and quad
-
- rlTexCoord2f(1.0f, 0.0f);
- rlVertex2f(position.x + texture.width, position.y); // Top-left corner for texture and quad
- rlEnd();
+ // NOTE: Rotation point is upper-left corner
+ rlPushMatrix();
+ rlTranslatef(position.x, position.y, 0.0);
+ rlScalef(scale, scale, 1.0f);
+ rlRotatef(rotation, 0, 0, 1);
+
+ rlBegin(RL_QUADS);
+ rlColor4ub(tint.r, tint.g, tint.b, tint.a);
+ rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
+
+ rlTexCoord2f(0.0f, 0.0f);
+ rlVertex2f(position.x, position.y); // Bottom-left corner for texture and quad
+
+ rlTexCoord2f(0.0f, 1.0f);
+ rlVertex2f(position.x, position.y + texture.height); // Bottom-right corner for texture and quad
+
+ rlTexCoord2f(1.0f, 1.0f);
+ rlVertex2f(position.x + texture.width, position.y + texture.height); // Top-right corner for texture and quad
+
+ rlTexCoord2f(1.0f, 0.0f);
+ rlVertex2f(position.x + texture.width, position.y); // Top-left corner for texture and quad
+ rlEnd();
+ rlPopMatrix();
rlDisableTexture();
}
@@ -337,32 +336,33 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
{
rlEnableTexture(texture.glId);
- // TODO: Apply translation, rotation and scaling of vertex manually!
-
- //rlTranslatef(-origin.x, -origin.y, 0);
- //rlRotatef(rotation, 0, 0, 1);
- //rlTranslatef(destRec.x + origin.x, destRec.y + origin.y, 0);
-
- rlBegin(RL_QUADS);
- rlColor4ub(tint.r, tint.g, tint.b, tint.a);
- rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
-
- // Bottom-left corner for texture and quad
- rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
- rlVertex2f(0.0f, 0.0f);
-
- // Bottom-right corner for texture and quad
- rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
- rlVertex2f(destRec.width, 0.0f);
-
- // Top-right corner for texture and quad
- rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
- rlVertex2f(destRec.width, destRec.height);
-
- // Top-left corner for texture and quad
- rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
- rlVertex2f(0.0f, destRec.height);
- rlEnd();
+ // NOTE: First we translate texture to origin to apply rotation and translation from there
+ rlPushMatrix();
+ rlTranslatef(-origin.x, -origin.y, 0);
+ rlRotatef(rotation, 0, 0, 1);
+ rlTranslatef(destRec.x + origin.x, destRec.y + origin.y, 0);
+
+ rlBegin(RL_QUADS);
+ rlColor4ub(tint.r, tint.g, tint.b, tint.a);
+ rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
+
+ // Bottom-left corner for texture and quad
+ rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
+ rlVertex2f(0.0f, 0.0f);
+
+ // Bottom-right corner for texture and quad
+ rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
+ rlVertex2f(destRec.width, 0.0f);
+
+ // Top-right corner for texture and quad
+ rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ rlVertex2f(destRec.width, destRec.height);
+
+ // Top-left corner for texture and quad
+ rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ rlVertex2f(0.0f, destRec.height);
+ rlEnd();
+ rlPopMatrix();
rlDisableTexture();
}
@@ -385,7 +385,7 @@ Texture2D CreateTexture(Image image)
j++;
}
- texture.glId = rlglTexture(image.width, image.height, img);
+ texture.glId = rlglLoadTexture(image.width, image.height, img);
texture.width = image.width;
texture.height = image.height;