diff --git a/GL/draw.c b/GL/draw.c index 01d9cf7..3d2d082 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -210,14 +210,14 @@ static void _readVertexData3fARGB(const GLubyte* in, GLubyte* output) { output[R8IDX] = (GLubyte) clamp(input[0] * 255.0f, 0, 255); output[G8IDX] = (GLubyte) clamp(input[1] * 255.0f, 0, 255); output[B8IDX] = (GLubyte) clamp(input[2] * 255.0f, 0, 255); - output[A8IDX] = 1.0f; + output[A8IDX] = 255; } static void _readVertexData3ubARGB(const GLubyte* __restrict__ input, GLubyte* __restrict__ output) { output[R8IDX] = input[0]; output[G8IDX] = input[1]; output[B8IDX] = input[2]; - output[A8IDX] = 1.0f; + output[A8IDX] = 255; } static void _readVertexData4ubRevARGB(const GLubyte* __restrict__ input, GLubyte* __restrict__ output) { diff --git a/GL/platforms/sh4.c b/GL/platforms/sh4.c index 404a2df..13bb99d 100644 --- a/GL/platforms/sh4.c +++ b/GL/platforms/sh4.c @@ -118,7 +118,6 @@ static inline void _glPushHeaderOrVertex(Vertex* v, size_t count) { } static inline void _glClipEdge(const Vertex* const v1, const Vertex* const v2, Vertex* vout) { - const static float o = 0.003921569f; // 1 / 255 const float d0 = v1->w + v1->xyz[2]; const float d1 = v2->w + v2->xyz[2]; const float t = (fabs(d0) * (1.0f / sqrtf((d1 - d0) * (d1 - d0)))); @@ -134,13 +133,10 @@ static inline void _glClipEdge(const Vertex* const v1, const Vertex* const v2, V vout->w = invt * v1->w + t * v2->w; - const float m = 255 * t; - const float n = 255 - m; - - vout->bgra[0] = (v1->bgra[0] * n + v2->bgra[0] * m) * o; - vout->bgra[1] = (v1->bgra[1] * n + v2->bgra[1] * m) * o; - vout->bgra[2] = (v1->bgra[2] * n + v2->bgra[2] * m) * o; - vout->bgra[3] = (v1->bgra[3] * n + v2->bgra[3] * m) * o; + vout->bgra[0] = invt * v1->bgra[0] + t * v2->bgra[0]; + vout->bgra[1] = invt * v1->bgra[1] + t * v2->bgra[1]; + vout->bgra[2] = invt * v1->bgra[2] + t * v2->bgra[2]; + vout->bgra[3] = invt * v1->bgra[3] + t * v2->bgra[3]; } #define SPAN_SORT_CFG 0x005F8030 diff --git a/GL/texture.c b/GL/texture.c index c6a0a0f..35ad164 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -1148,6 +1148,26 @@ GL_FORCE_INLINE void _rgba4444_to_argb4444(const GLubyte* source, GLubyte* dest) *((GLushort*) dest) = ((*src & 0x000F) << 12) | *src >> 4; } +GL_FORCE_INLINE void _argb1555_to_argb4444(const GLubyte* source, GLubyte* dest) { + GLushort src = *((GLushort*) source); + + uint8_t a = (src >> 15) & 0x01; + uint8_t r = (src >> 10) & 0x1F; + uint8_t g = (src >> 5) & 0x1F; + uint8_t b = src & 0x1F; + + // Alpha is either 0 or 15 + a = (a << 4) - a; + + // Bitwise magic to scale from 5 to 4 bits. + // Shift left by 4 to multiply by 16, shift right by 5 to divide by 32. + r = (r << 4) >> 5; + g = (g << 4) >> 5; + b = (b << 4) >> 5; + + *((GLushort*) dest) = (a << 12) | (r << 8) | (g << 4) | b; +} + GL_FORCE_INLINE void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest) { GLushort src = *((GLushort*) source); GLubyte* dst = (GLubyte*) dest; @@ -1216,6 +1236,7 @@ static int _determineConversion(GLint internalFormat, GLenum format, GLenum type {NULL, GL_ARGB4444_TWID_KOS, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS, false, false}, {_rgba8888_to_argb4444, GL_ARGB4444_TWID_KOS, GL_RGBA, GL_UNSIGNED_BYTE, true, false}, {NULL, GL_ARGB1555_KOS, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, false, false}, + {_argb1555_to_argb4444, GL_ARGB4444_TWID_KOS, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, true, false}, {NULL, GL_ARGB1555_TWID_KOS, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS, false, false}, {_rgba8888_to_rgb565, GL_RGB565_KOS, GL_RGBA, GL_UNSIGNED_BYTE, false, false}, {_r8_to_rgb565, GL_RGB565_KOS, GL_RED, GL_UNSIGNED_BYTE, false, false}, diff --git a/samples/cubes/main.cpp b/samples/cubes/main.cpp index 1599466..b42063b 100644 --- a/samples/cubes/main.cpp +++ b/samples/cubes/main.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -18,10 +17,12 @@ float avgfps = -1; #define RAD_TO_DEG 57.295779513082320876798154814105f #define MAX_CUBES 350 +size_t numCubes = 0; + float timeElapsed = 0.0f; const float dt = 1.0f / 60.0f; -float angle = 0; +float angleDegrees = 0; const float invAngle360 = 1.0f / 360.0f; const float cameraDistance = 3.0f; @@ -84,7 +85,7 @@ float cubeVertices[] = -1.0f, -1.0f, +1.0f, // vertex 20 -1.0f, -1.0f, -1.0f, // vertex 21 -1.0f, +1.0f, -1.0f, // vertex 22 - -1.0f, +1.0f, +1.0f // vertex 23 + -1.0f, +1.0f, +1.0f // vertex 23 }; // Set up indices array @@ -117,17 +118,11 @@ typedef struct } Cube; Cube cubes[MAX_CUBES]; - -int numCubes = 0; - -// Create a 4x4 identity matrix -float cubeTransformationMatrix[16] = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }; +float lutScaleFactors[MAX_CUBES]; -void debugLog(const char* msg) { +void debugLog(const char* msg) +{ #ifdef __DREAMCAST__ dbglog(DBG_KDEBUG, "%s\n", msg); #else @@ -136,7 +131,8 @@ void debugLog(const char* msg) { } -void runningStats() { +void runningStats() +{ #ifdef __DREAMCAST__ pvr_stats_t stats; pvr_get_stats(&stats); @@ -148,14 +144,17 @@ void runningStats() { #endif } -void avgStats() { + +void avgStats() +{ #ifdef __DREAMCAST__ dbglog(DBG_DEBUG, "Average frame rate: ~%f fps\n", avgfps); #endif } -void stats() { +void stats() +{ #ifdef __DREAMCAST__ pvr_stats_t stats; @@ -166,9 +165,10 @@ void stats() { } -void addCube(float r, float x, float y, float z, float vx, float vy, float vz) +void addCube(const float r, const float x, const float y, const float z, const float vx, const float vy, const float vz) { - if (numCubes < MAX_CUBES) { + if (numCubes < MAX_CUBES) + { cubes[numCubes].r = r; cubes[numCubes].x = x; cubes[numCubes].y = y; @@ -181,24 +181,18 @@ void addCube(float r, float x, float y, float z, float vx, float vy, float vz) } -void addCubeQuick(float x, float y, float z, float scale_factor) -{ - addCube(0.5f * scale_factor, x, y, z, 0, 0, 0); -} - - void updateCubes(float dt) { - for (size_t i = 0; i < numCubes; i++) + for (size_t i = 0; i < MAX_CUBES; i++) { - Cube* cube = &cubes[i]; - cube->x += cube->vx * dt; - cube->y += cube->vy * dt; - cube->z += cube->vz * dt; + Cube* pCube = &cubes[i]; + pCube->x += pCube->vx * dt; + pCube->y += pCube->vy * dt; + pCube->z += pCube->vz * dt; - if (cube->x < -3 || cube->x > +3) { cube->vx *= -1; } - if (cube->y < -3 || cube->y > +3) { cube->vy *= -1; } - if (cube->z < -3 || cube->z > +3) { cube->vz *= -1; } + if (pCube->x < -3 || pCube->x > +3) { pCube->vx *= -1; } + if (pCube->y < -3 || pCube->y > +3) { pCube->vy *= -1; } + if (pCube->z < -3 || pCube->z > +3) { pCube->vz *= -1; } } } @@ -211,31 +205,27 @@ void renderUnitCube() glVertexPointer(3, GL_FLOAT, 0, cubeVertices); glColorPointer(4, GL_UNSIGNED_BYTE, 0, faceColors); - if (isDrawingArrays) { - glDrawArrays(GL_QUADS, 0, 24); - } - else { - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, cubeIndices); - } + isDrawingArrays ? glDrawArrays(GL_QUADS, 0, 24) : glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, cubeIndices); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } -void renderCubes(float angle) +void renderCubes(const float angleRotation) { - for (size_t i = 0; i < numCubes; i++) { - const float scale_factor = 0.05f + (i / (float)numCubes) * 0.35f; - Cube* cube = &cubes[i]; + for (size_t i = 0; i < MAX_CUBES; i++) + { + const float scaleFactor = lutScaleFactors[i]; + Cube* pCube = &cubes[i]; glPushMatrix(); // Save previous camera state glMatrixMode(GL_MODELVIEW); - glTranslatef(cube->x, cube->y, cube->z); - glRotatef(angle, 1, 1, 1); // Rotate camera / object + glTranslatef(pCube->x, pCube->y, pCube->z); + glRotatef(angleRotation, 1, 1, 1); // Rotate camera / object - glScalef(scale_factor, scale_factor, scale_factor); // Apply scale factor + glScalef(scaleFactor, scaleFactor, scaleFactor); // Apply scale factor renderUnitCube(); glPopMatrix(); // Restore previous camera state @@ -243,9 +233,9 @@ void renderCubes(float angle) } -float rnd(float Min, float Max) +float rnd(float valueMin, float valueMax) { - return (Max - Min) * (float)rand() / (float)RAND_MAX + Min; + return (valueMax - valueMin) * (float)rand() / (float)RAND_MAX + valueMin; } @@ -279,13 +269,20 @@ void initialize() glLoadIdentity(); // Set up colors (each face has a different color) - for (int i = 0; i < 6; i++) + for (size_t i = 0; i < 6; i++) { faceColors[i * 4] = colors[i]; faceColors[i * 4 + 1] = colors[i]; faceColors[i * 4 + 2] = colors[i]; faceColors[i * 4 + 3] = colors[i]; } + + // Precalculate scale factors and store them in a LUT + const float incFactor = 0.35f / (float)MAX_CUBES; + for (size_t i = 0; i < MAX_CUBES; ++i) + { + lutScaleFactors[i] = 0.05f + (i * incFactor); + } } @@ -305,9 +302,9 @@ void updateLogic() { updateTimer(); - const int fullRot = (int)(angle * invAngle360); - angle -= fullRot * 360.0f; - angle += 50.0f * dt; + const int fullRot = (int)(angleDegrees * invAngle360); + angleDegrees -= fullRot * 360.0f; + angleDegrees += 50.0f * dt; const float zoomVal = __builtin_sinf(timeElapsed) * 5.0f; @@ -332,7 +329,7 @@ void updateLogic() updateCubes(dt); - renderCubes(angle); + renderCubes(angleDegrees); // Reset ModelView matrix to remove camera transformation float matrix[16]; @@ -368,28 +365,14 @@ void updateInput() { isDrawingArrays = !isDrawingArrays; - if (isDrawingArrays) - { - glClearColor(0.3f, 0.0f, 0.3f, 1.0f); - } - else - { - glClearColor(0.0f, 0.0f, 0.3f, 1.0f); - } + isDrawingArrays ? glClearColor(0.3f, 0.0f, 0.3f, 1.0f) : glClearColor(0.0f, 0.0f, 0.3f, 1.0f); } if (state && (state->buttons & CONT_B) && !(prevButtons & CONT_B)) { isBlendingEnabled = !isBlendingEnabled; - if (isBlendingEnabled) - { - glEnable(GL_BLEND); - } - else - { - glDisable(GL_BLEND); - } + isBlendingEnabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND); } prevButtons = state->buttons; @@ -420,7 +403,6 @@ int main(int argc, char* argv[]) for (size_t i = 0; i < MAX_CUBES; i++) { - const float r = rnd(0.1f, 0.5f); const float x = rnd(-3.0f, 3.0f); const float y = rnd(-3.0f, 3.0f);