[gnome-games/glchess-vala] Add piece and board texturing



commit d230c0ac894224d4ec743cddd438a4bf83c5240b
Author: Robert Ancell <robert ancell canonical com>
Date:   Thu Jan 6 09:42:42 2011 +1100

    Add piece and board texturing

 glchess/src/3ds.vala           |   29 +++++++++++++-
 glchess/src/chess-view-3d.vala |   84 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 103 insertions(+), 10 deletions(-)
---
diff --git a/glchess/src/3ds.vala b/glchess/src/3ds.vala
index 0d44ce1..ace7813 100644
--- a/glchess/src/3ds.vala
+++ b/glchess/src/3ds.vala
@@ -2,9 +2,12 @@ using GL;
 
 public class TDSModel
 {
+    private GLfloat min_height = float.MAX;
+    private GLfloat max_height = float.MIN;
     private GLfloat[] vertices;
     private GLushort[] triangles;
     private GLfloat[] normals;
+    private GLfloat[] texture_coords;
 
     public TDSModel (File file) throws Error
     {
@@ -53,6 +56,15 @@ public class TDSModel
             normals[i+1] /= length;
             normals[i+2] /= length;
         }
+
+        /* Set texture coordinates to a cylindrical projection */
+        // FIXME: Use something more eliptical so the tops don't look quite so distorted
+        texture_coords = new GLfloat[(vertices.length / 3) * 2];
+        for (int i = 0, j = 0; i < vertices.length; i += 3, j += 2)
+        {
+            texture_coords[j] = (GLfloat) (Math.atan2 (vertices[i], vertices[i+2]) / (2 * Math.PI)) + 0.5f;
+            texture_coords[j+1] = (vertices[i+1] - min_height) / max_height;
+        }        
     }
     
     private void parse_block (FileInputStream stream, int64 length) throws Error
@@ -68,7 +80,7 @@ public class TDSModel
             if (block_length > length)
             {
                 // throw error
-                stderr.printf("Overflow, need %lli octets for %04X, but only have %lli\n", block_length, id, length);
+                stderr.printf("Overflow, need %lli octets for %04X, but only have %lli\n", block_length, (int) id, length);
                 return;
             }
 
@@ -123,6 +135,13 @@ public class TDSModel
                     vertices[i*3] = scale*x;
                     vertices[i*3+1] = scale*z;
                     vertices[i*3+2] = scale*y;
+
+                    var h = scale*z;
+                    if (h < min_height)
+                        min_height = h;
+                    if (h > max_height)
+                        max_height = h;
+
                     //stdout.printf ("<vertex x=\"%f\" y=\"%f\" z=\"%f\"/>\n", x, y, z);
                 }
                 //stdout.printf("</vertices>\n");
@@ -188,11 +207,17 @@ public class TDSModel
         glEnable (GL_CULL_FACE);
 
         glEnableClientState (GL_VERTEX_ARRAY);
-        glVertexPointer (3, GL_FLOAT, 0, vertices);
         glEnableClientState (GL_NORMAL_ARRAY);
+        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+
+        glVertexPointer (3, GL_FLOAT, 0, vertices);
         glNormalPointer (GL_FLOAT, 0, normals);
+        glTexCoordPointer (2, GL_FLOAT, 0, texture_coords);
         glDrawElements (GL_TRIANGLES, (GLsizei) triangles.length, GL_UNSIGNED_SHORT, triangles);
+
         glDisableClientState (GL_VERTEX_ARRAY);
+        glDisableClientState (GL_NORMAL_ARRAY);
+        glDisableClientState (GL_TEXTURE_COORD_ARRAY);
     }
 
     private uint8 read_uint8 (InputStream stream) throws Error
diff --git a/glchess/src/chess-view-3d.vala b/glchess/src/chess-view-3d.vala
index dfadc94..b13c645 100644
--- a/glchess/src/chess-view-3d.vala
+++ b/glchess/src/chess-view-3d.vala
@@ -27,12 +27,24 @@ private class ChessView3D : ChessView
     private GLfloat BOARD_OUTER_WIDTH;
     private GLfloat OFFSET;
 
+    private GLuint _board_texture = 0;
+    private GLuint board_texture
+    {
+        get { if (_board_texture == 0) _board_texture = load_texture (Path.build_filename (Config.PKGDATADIR, "textures", "board.png", null)); return _board_texture; }
+    }
+
     private GLuint _numbering_texture = 0;
     private GLuint numbering_texture
     {
         get { if (_numbering_texture == 0) _numbering_texture = make_numbering_texture (); return _numbering_texture; }
     }
 
+    private GLuint _piece_texture = 0;
+    private GLuint piece_texture
+    {
+        get { if (_piece_texture == 0) _piece_texture = load_texture (Path.build_filename (Config.PKGDATADIR, "textures", "piece.png", null)); return _piece_texture; }
+    }
+
     public ChessView3D ()
     {
         SQUARE_WIDTH = 10.0f;
@@ -114,7 +126,7 @@ private class ChessView3D : ChessView
                           f, -BOARD_CHAMFER, l,  a, -BOARD_CHAMFER, l,
                           a, -BOARD_DEPTH, g,  f, -BOARD_DEPTH, g,  f, -BOARD_DEPTH, l,  a, -BOARD_DEPTH, l};
         board_quads = {0, 1, 5, 4,  0, 4, 7, 3,  3, 7, 6, 2,  2, 6, 5, 1,
-                      4, 5, 9, 8,  4, 8, 11, 7,  7, 11, 10, 6,  6, 10, 9, 5};
+                       4, 5, 9, 8,  4, 8, 11, 7,  7, 11, 10, 6,  6, 10, 9, 5};
     }
     
     private void realize_cb ()
@@ -226,7 +238,7 @@ private class ChessView3D : ChessView
             else
                 gluPerspective (60.0f, (float) get_allocated_width () / get_allocated_height (), 0.1f, 1000);
 
-            glMatrixMode(GL_MODELVIEW);
+            glMatrixMode (GL_MODELVIEW);
             transform_camera ();
 
             GLfloat[] pos = { 100.0f, 100.0f, 100.0f, 1.0f };
@@ -268,6 +280,8 @@ private class ChessView3D : ChessView
 
         var selected_piece = options.get_selected_piece ();
 
+        glEnable (GL_TEXTURE_2D);
+        glBindTexture (GL_TEXTURE_2D, board_texture);
         glNormal3f (0.0f, 1.0f, 0.0f);
         for (var rank = 0; rank < 8; rank++)
             for (var file = 0; file < 8; file++)
@@ -304,12 +318,18 @@ private class ChessView3D : ChessView
                 GLfloat z0 = BOARD_BORDER + (rank * SQUARE_WIDTH);
                 GLfloat z1 = z0 + SQUARE_WIDTH;
 
-                glVertex3f(x0, 0.0f, -z0);
-                glVertex3f(x1, 0.0f, -z0);
-                glVertex3f(x1, 0.0f, -z1);
-                glVertex3f(x0, 0.0f, -z1);
+                glTexCoord2f (0.0f, 0.0f);
+                glVertex3f (x0, 0.0f, -z0);
+                glTexCoord2f (1.0f, 0.0f);
+                glVertex3f (x1, 0.0f, -z0);
+                glTexCoord2f (1.0f, 1.0f);
+                glVertex3f (x1, 0.0f, -z1);
+                glTexCoord2f (0.0f, 1.0f);
+                glVertex3f (x0, 0.0f, -z1);
                 glEnd ();
             }
+
+        glDisable (GL_TEXTURE_2D);
         glDisable (GL_COLOR_MATERIAL);
     }
 
@@ -375,7 +395,10 @@ private class ChessView3D : ChessView
             return;
 
         glEnable (GL_DEPTH_TEST);
+        glEnable (GL_TEXTURE_2D);
         glEnable (GL_COLOR_MATERIAL);
+        glBindTexture (GL_TEXTURE_2D, piece_texture);
+
         for (int rank = 0; rank < 8; rank++)
         {
             for (int file = 0; file < 8; file++)
@@ -396,7 +419,7 @@ private class ChessView3D : ChessView
 
                 glPushMatrix ();
                 glTranslatef (BOARD_BORDER + file * SQUARE_WIDTH + SQUARE_WIDTH / 2, 0.0f, -(BOARD_BORDER + rank * SQUARE_WIDTH + SQUARE_WIDTH / 2));
-                
+
                 if (piece.player.color == Color.BLACK)
                     glRotatef (180.0f, 0.0f, 1.0f, 0.0f);
 
@@ -426,6 +449,7 @@ private class ChessView3D : ChessView
             }
         }
 
+        glDisable (GL_TEXTURE_2D);
         glDisable (GL_COLOR_MATERIAL);
     }
 
@@ -503,7 +527,51 @@ private class ChessView3D : ChessView
                   0.0,  0.0, 5.0,
                   0.0,  1.0,  0.0);
     }
-    
+
+    private GLuint load_texture (string filename)
+    {
+        Gdk.Pixbuf pixbuf;
+        try
+        {
+            pixbuf = new Gdk.Pixbuf.from_file (filename);
+        }
+        catch (Error e)
+        {
+            warning ("Error loading texture %s: %s", filename, e.message);
+            return 0;
+        }
+
+        GLenum format;
+        if (pixbuf.n_channels == 1)
+            format = GL_LUMINANCE;
+        else if (pixbuf.n_channels == 3)
+            format = GL_RGB;
+        else if (pixbuf.n_channels == 4)
+            format = GL_RGBA;
+        else
+        {
+            warning ("Unknown format image");
+            return 0;
+        }
+
+        GLuint textures[1];
+        glGenTextures (1, textures);
+        var t = textures[0];
+        glBindTexture (GL_TEXTURE_2D, t);
+        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+        gluBuild2DMipmaps (GL_TEXTURE_2D, (GLint) pixbuf.n_channels, (GLsizei) pixbuf.width, (GLsizei) pixbuf.height,
+                           format, GL_UNSIGNED_BYTE, pixbuf.pixels);
+        // FIXME: How to check if failed
+        //    glTexImage2D (GL_TEXTURE_2D, 0, pixbuf.n_channels, (GLsizei) pixbuf.width, (GLsizei) pixbuf.height, 0, format, GL_UNSIGNED_BYTE, pixbuf.pixels);
+            
+        return t;       
+    }
+
     private GLuint make_numbering_texture ()
     {
         int width = 64, height = 64;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]