OSDN Git Service

implement tx_compress_dxtn
authorRudolf Polzer <divverent@xonotic.org>
Tue, 12 Jul 2011 18:42:49 +0000 (20:42 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Thu, 14 Jul 2011 17:12:23 +0000 (19:12 +0200)
s2tc.cpp
s2tc_compressor.cpp
s2tc_compressor.h
s2tc_libtxc_dxtn.c

index bdf5c40..4b2728f 100644 (file)
--- a/s2tc.cpp
+++ b/s2tc.cpp
@@ -657,7 +657,7 @@ int main(int argc, char **argv)
        unsigned char *opic = (unsigned char *) malloc(image_width * image_height * 4);
        for(;;)
        {
-               rgb565_image(opic, pic, image_width, image_height, alpharange);
+               rgb565_image(opic, pic, image_width, image_height, 4, 1, alpharange);
                for(y = 0; y < image_height; y += 4)
                        for(x = 0; x < image_width; x += 4)
                        {
index 9ef5310..dbd81e5 100644 (file)
@@ -517,20 +517,38 @@ namespace
        }
 };
 
-void rgb565_image(unsigned char *out, const unsigned char *rgba, int w, int h, int alpharange)
+void rgb565_image(unsigned char *out, const unsigned char *rgba, int w, int h, int srccomps, int bgr, int alpharange)
 {
        int x, y;
        float diffuse_r = 0;
        float diffuse_g = 0;
        float diffuse_b = 0;
        float diffuse_a = 0;
-       for(y = 0; y < h; ++y)
-               for(x = 0; x < w; ++x)
-               {
-                       out[(x + y * w) * 4 + 2] = diffuse(&diffuse_r, rgba[(x + y * w) * 4 + 2] * 31.0 / 255.0);
-                       out[(x + y * w) * 4 + 1] = diffuse(&diffuse_g, rgba[(x + y * w) * 4 + 1] * 63.0 / 255.0);
-                       out[(x + y * w) * 4 + 0] = diffuse(&diffuse_b, rgba[(x + y * w) * 4 + 0] * 31.0 / 255.0);
-                       out[(x + y * w) * 4 + 3] = diffuse(&diffuse_a, rgba[(x + y * w) * 4 + 3] * (alpharange / 255.0));
-               }
+       if(bgr)
+       {
+               for(y = 0; y < h; ++y)
+                       for(x = 0; x < w; ++x)
+                       {
+                               out[(x + y * w) * 4 + 2] = diffuse(&diffuse_r, rgba[(x + y * w) * srccomps + 2] * 31.0 / 255.0);
+                               out[(x + y * w) * 4 + 1] = diffuse(&diffuse_g, rgba[(x + y * w) * srccomps + 1] * 63.0 / 255.0);
+                               out[(x + y * w) * 4 + 0] = diffuse(&diffuse_b, rgba[(x + y * w) * srccomps + 0] * 31.0 / 255.0);
+                       }
+       }
+       else
+       {
+               for(y = 0; y < h; ++y)
+                       for(x = 0; x < w; ++x)
+                       {
+                               out[(x + y * w) * 4 + 2] = diffuse(&diffuse_r, rgba[(x + y * w) * srccomps + 0] * 31.0 / 255.0);
+                               out[(x + y * w) * 4 + 1] = diffuse(&diffuse_g, rgba[(x + y * w) * srccomps + 1] * 63.0 / 255.0);
+                               out[(x + y * w) * 4 + 0] = diffuse(&diffuse_b, rgba[(x + y * w) * srccomps + 2] * 31.0 / 255.0);
+                       }
+       }
+       if(srccomps == 4)
+       {
+               for(y = 0; y < h; ++y)
+                       for(x = 0; x < w; ++x)
+                               out[(x + y * w) * 4 + 3] = diffuse(&diffuse_a, rgba[(x + y * w) * srccomps + 3] * (alpharange / 255.0));
+       }
 }
 
index 256f3b9..ff55e34 100644 (file)
@@ -7,7 +7,7 @@
 extern "C" {
 #endif
 
-void rgb565_image(unsigned char *out, const unsigned char *rgba, int w, int h, int alpharange);
+void rgb565_image(unsigned char *out, const unsigned char *rgba, int w, int h, int srccomps, int bgr, int alpharange);
 
 typedef enum
 {
index f035cf5..c9cd75a 100644 (file)
 #include "s2tc_compressor.h"
 
 #include <GL/gl.h>
+#include <stdlib.h>
+#include <stdio.h>
 
 void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata,
                             GLint i, GLint j, GLvoid *texel)
 {
+       // fetches a single texel (i,j) into pixdata (RGB)
+       // TODO
 }
 
 void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata,
                             GLint i, GLint j, GLvoid *texel)
 {
+       // fetches a single texel (i,j) into pixdata (RGBA)
+       // TODO
 }
 
 void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata,
                             GLint i, GLint j, GLvoid *texel)
 {
+       // fetches a single texel (i,j) into pixdata (RGBA)
+       // TODO
 }
 
 void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata,
                             GLint i, GLint j, GLvoid *texel)
 {
+       // fetches a single texel (i,j) into pixdata (RGBA)
+       // TODO
 }
 
 void tx_compress_dxtn(GLint srccomps, GLint width, GLint height,
-                     const GLubyte *srcPixData, GLenum destformat,
+                     const GLubyte *srcPixData, GLenum destFormat,
                      GLubyte *dest, GLint dstRowStride)
 {
+       // compresses width*height pixels (RGB or RGBA depending on srccomps) at srcPixData (packed) to destformat (dest, dstRowStride)
+
+       GLubyte *blkaddr = dest;
+       GLint numxpixels, numypixels;
+       GLint i, j;
+       GLint dstRowDiff;
+       unsigned char *rgba = malloc(width * height * 4);
+       unsigned char *srcaddr;
+
+       switch (destFormat) {
+               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+                       rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 1);
+                       break;
+               case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+                       rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 15);
+                       break;
+               case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+                       rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 255);
+                       break;
+               default:
+                       free(rgba);
+                       fprintf(stderr, "libdxtn: Bad dstFormat %d in tx_compress_dxtn\n", destFormat);
+                       return;
+       }
+
+       switch (destFormat) {
+               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+                       /* hmm we used to get called without dstRowStride... */
+                       dstRowDiff = dstRowStride >= (width * 2) ? dstRowStride - (((width + 3) & ~3) * 2) : 0;
+                       /*      fprintf(stderr, "dxt1 tex width %d tex height %d dstRowStride %d\n",
+                               width, height, dstRowStride); */
+                       for (j = 0; j < height; j += 4) {
+                               if (height > j + 3) numypixels = 4;
+                               else numypixels = height - j;
+                               srcaddr = rgba + j * width * 4;
+                               for (i = 0; i < width; i += 4) {
+                                       if (width > i + 3) numxpixels = 4;
+                                       else numxpixels = width - i;
+                                       s2tc_encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, DXT1, SRGB_MIXED, 0);
+                                       srcaddr += 4 * numxpixels;
+                                       blkaddr += 8;
+                               }
+                               blkaddr += dstRowDiff;
+                       }
+                       break;
+               case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+                       dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
+                       /*      fprintf(stderr, "dxt3 tex width %d tex height %d dstRowStride %d\n",
+                               width, height, dstRowStride); */
+                       for (j = 0; j < height; j += 4) {
+                               if (height > j + 3) numypixels = 4;
+                               else numypixels = height - j;
+                               srcaddr = rgba + j * width * 4;
+                               for (i = 0; i < width; i += 4) {
+                                       if (width > i + 3) numxpixels = 4;
+                                       else numxpixels = width - i;
+                                       s2tc_encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, DXT3, SRGB_MIXED, 0);
+                                       srcaddr += 4 * numxpixels;
+                                       blkaddr += 16;
+                               }
+                               blkaddr += dstRowDiff;
+                       }
+                       break;
+               case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+                       dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
+                       /*      fprintf(stderr, "dxt5 tex width %d tex height %d dstRowStride %d\n",
+                               width, height, dstRowStride); */
+                       for (j = 0; j < height; j += 4) {
+                               if (height > j + 3) numypixels = 4;
+                               else numypixels = height - j;
+                               srcaddr = rgba + j * width * 4;
+                               for (i = 0; i < width; i += 4) {
+                                       if (width > i + 3) numxpixels = 4;
+                                       else numxpixels = width - i;
+                                       s2tc_encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, DXT5, SRGB_MIXED, 0);
+                                       srcaddr += 4 * numxpixels;
+                                       blkaddr += 16;
+                               }
+                               blkaddr += dstRowDiff;
+                       }
+                       break;
+       }
+
+       free(rgba);
 }