หลังจากห่างหายกับเรื่องการวาดตัวอักษรไปนาน วันนี้จะมาอัพเดตเรื่องนี้สักเล็กน้อย

ในตัวอย่างเก่า ๆ ผมใช้การสร้าง SDL_Surface ขึ้นมาแล้วเรียก SDL_CreateTextureFromSurface() ในการสร้าง Texture ก่อนที่จะวาดลงไป วิธีนี้มีข้อเสียเพราะว่าเราจะมี object ใช้แล้วทิ้งเพิ่มมาหนึ่งตัว ซึ่งถ้าเราสามารถลดตรงนี้ไปได้โค๊ดเราก็จะทำงานได้อย่างมีประสิทธิภาพมากขึ้นครับ

โค๊ดก็ไม่ได้มีอะไรซับซ้อนเลย

SDL_Texture* CreateTextureFromFT_Bitmap(SDL_Renderer* renderer,
                                        const FT_Bitmap& bitmap,
                                        const SDL_Color& color)
{
    SDL_Texture* output = SDL_CreateTexture(renderer,
            SDL_PIXELFORMAT_RGBA8888,
            SDL_TEXTUREACCESS_STREAMING,
            bitmap.width,
            bitmap.rows);

    void *buffer;
    int pitch;
    SDL_LockTexture(output, NULL, &buffer, &pitch);

    unsigned char *src_pixels = bitmap.buffer;
    unsigned int *target_pixels = reinterpret_cast<unsigned int*>(buffer);

    SDL_PixelFormat* pixel_format = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888);

    for (int y = 0; y < bitmap.rows; y++)
    {
        for (int x = 0; x < bitmap.width; x++)
        {
            int index = (y * bitmap.width) + x;
            unsigned int alpha = src_pixels[index];
            unsigned int pixel_value =
                    SDL_MapRGBA(pixel_format, color.r, color.g, color.b, alpha);

            target_pixels[index] = pixel_value;
        }
    }

    SDL_FreeFormat(pixel_format);
    SDL_UnlockTexture(output);

    return output;
}

ผมเปลี่ยนไปใช้ return statement แทนการใช้ pass-by-reference นะครับ โค๊ดจะอ่านง่ายขึ้นพอสมควร ส่วนการเอาไปใช้ก็เหมือนเดิมครับ อาจจะต้องปรับเปลี่ยนโค๊ดเดิมนิดหน่อยแต่ก็ไม่เกินความสามารถกันอยู่แล้ว

โค๊ดชุดนี้มีการลดการใช้ hardcode ในส่วนของการคำนวนค่าในแต่ละ pixel ลง จากของเก่าจะเป็นการยึด format มาเลย ก็เปลี่ยนมาใช้ SDL_MapRGBA() แทน แต่โค๊ดนี้ก็ยังอยู่ภายใต้ข้อจำกัดที่ว่าแต่ละ pixel นั้นมีขนาด 4 byte อันนี้อาจจะมีการแก้ไขในอนาคตครับ

อ่านแล้วก็ไปลองเล่นกันดูนะครับ :-)

ไม่รู้ว่ามีใครยังติดตาม series นี้อยู่หรือเปล่า เขียนนานเหลือเกิน คนเขียนช่วงนี้สุขภาพหัวใจไม่ค่อยดีครับก็เลยหักโหมมากไม่ได้น่ะ 😛

ช่วงการวาดแบบ Raster นี่ ผมจะขออนุญาตแบ่งเป็นตอน ๆ นะครับ เพราะว่าตรงนี้จะเริ่มลงไปรายละเอียดแล้ว คงจะยาวทีเดียว

ก่อนอื่นขอออกตัวก่อนว่า ผมจะเขียนการวาดตัวหนังสือแบบ Vector รวมกับแบบ Raster ไปเลย  เหตุผลก็คือระบบกราฟิคในปัจจุบันนั้นการวาดในระดับล่างจะเป็นแบบ Raster ทั้งหมด การวาดกราฟิคแบบ Vector นั้นตัว Output ที่ได้จะถูกแปลงกลับมาเป็น Raster ก่อนที่จะแสดงผลออกทางหน้าจอ เป็นขั้นตอนที่เรียกกว่า Rasterization (สำหรับ การวาดภาพบนหน้าจอแบบ Vector คือการวาดที่ใช้จอแบบ CRT แบบโบราณที่ตัวปืนยิงรังสีจะขยับตาม Input ซึ่งถ้าอยากเห็นของจริงก็คงต้องไปพิพิธภัณฑ์ล่ะครับ) ...continue reading เรื่องวุ่น ๆ กับตัวหนังสือ – ตอนที่ 6 – วาดตัวหนังสือแบบ Raster ส่วนที่ 1

สมัยนี้หลาย ๆ คนอาจจะคิดว่าเราคงไม่ได้เขียนเกมแบบ Tile Base แท้ ๆ กันแล้ว ซึ่งก็คงจะจริงเพราะว่าส่วนใหญ่เราจะใช้การวาดกราฟิคแบบ 3D กันหมดแล้ว (ผ่าน OpenGL หรือ API อะไรก็แล้วแต่) แต่ผมว่าเรื่อง Tile Base เนี่ยมันน่าสนใจนะครับ แล้วมันก็คลาสสิคด้วย

image

ภาพข้างบนผมจับมาจากเกมที่ชื่อว่า Lufia II : Sin of Sinistral ซึ่งเป็นภาคแปลจากเกมที่ชื่อว่า Espolis Biography II … เกมนี้เป็นเกมที่ผมชอบมากเมื่อสมัยเด็ก ๆ เพราะเป็นเกมที่ต้องใช้ความคิดในการแก้ปริศนาเยอะมาก (ยากด้วย) ปัจจุบันมีการ Remake เกมนี้ขึ้นมาใหม่ กลายเป็น Lufia ภาคแรกไป (เพราะเนื้อเรื่องภาคนี้จะอยู่ก่อนหน้าอีกภาคนึง) ซึ่งไม่สนุกเหมือนตัวเก่า แต่ก็ออกมาแล้วหายคิดถึงไปเยอะเลย

...continue reading เรื่องวุ่น ๆ กับตัวหนังสือ – ตอนที่ 5 – วาดตัวหนังสือแบบ Tile-Base

อย่างที่เคยบอกว่า Font คือ ชุดของตัวอักษร ถ้าจะให้อธิบายให้ละเอียดยิ่งขึ้น Font ก็คือ ชุดของภาพตัวอักษร (Glyph) ครับ

เราสามารถแบ่งประเภทของ Font ได้จากลักษณะของ Glyph ที่มันเก็บเอาไว้ได้สองลักษณะ ดังนี้

1. Raster Font

Raster Font ก็คือ Font ที่เก็บ Glyph ในลักษณะของ Raster … ก็คือ … Bitmap น่ะล่ะครับ

image

Font ในยุคต้น ๆ จะเป็น Raster ทั้งหมด เพราะว่าเครื่อง PC ในสมัยนั้นมีความสามารถต่ำ และ คนที่สร้างฟอนท์เองก็ไม่ได้เก่งอะไร (อย่าลืมว่าคอมพิวเตอร์ในยุคแรก ๆ นั้นผู้ใช้เป็นคนที่อยู่ในวงการคอมพิวเตอร์ และคณิตศาสตร์ เสียส่วนใหญ่นะครับ) การวาดฟอนท์ด้วยภาพ Bitmap นั้นไม่ได้ยากมาก แต่อาจจะดูไม่สวยอยู่สักหน่อย

...continue reading เรื่องวุ่น ๆ กับตัวหนังสือ – ตอนที่ 4 – ประเภทของ Font

บทที่แล้วมีเกริ่นถึง Character Encoding ไปนิดหน่อย ก็อย่างที่บอกว่า Encoding ก็คือ วิธีเข้ารหัสตัวอักษรให้อยู่ในรูปของรหัสที่คอมพิวเตอร์แยกแยะและนำไปใช้ได้ บทนี้เราจะพูดถึงรายละเอียดลึกลงไปหน่อยว่า เทคนิคการ Encoding ทั่ว ๆ ไป ที่ใช้ ๆ กันในมาตรฐานต่าง ๆ นั้นมันเป็นยังไงบ้าง

บทนี้จะพูดถึงเรื่อง Technical ล้วน ๆ ครับ ใครอยู่สายอื่นอาจจะไม่ต้องทำความเข่้าใจมันมากก็ได้ อันที่จริงมันไม่ค่อยมีประโยชน์ต่อคนในสาย Artist/Designer เท่าไหร่หรอก

...continue reading เรื่องวุ่น ๆ กับตัวหนังสือ – ตอนที่ 3 – Character Encoding

Character แปลตรง ๆ ตัว ก็คือ ตัวอักษร ส่วน Glyph ในความหมายของ Typography หมายถึง ภาพตัวอักษร

ถึงตรงนี้หลาย ๆ คนคงเดาออกแล้วว่าอะไรคืออะไร แต่ถ้ายังไม่รู้ ก็อ่านต่อเลยครับ

Character

คราวนี้จะมีเทคนิคัลเข้ามานิด ๆ นะครับ ไม่ต้องกังวลนะ ยังไม่ลงไปรายละเอียดครับ

สิ่งที่เราใช้แยกแยะตัวอักษรนั้นก็คือ ภาพของตัวอักษร (Glyph) และ เราเรียกตัวอักษรใด ๆ ด้วยชื่อ (Character Name) อย่างเช่น เราเรียก ก ว่า "กอไก่" หรือ A ว่า "เอ"

...continue reading เรื่องวุ่น ๆ กับตัวหนังสือ – ตอนที่ 2 – Character vs Glyph

บทความนี้ยกยอดมาจากที่ผมเขียนเอาไว้ใน TGDX นะครับ

สวัสดีครับ วันนี้อยากจะพูดเรื่องตัุวหนังสือกับเกมเสียหน่อย ไม่รู้จะมีใครสนใจมั้ย (แฮ่) จริง ๆ ว่าจะเขียนมาตั้งแต่สองปีที่แล้วแล้ว 55 เอาเถอะ เริ่มเลยละกัน

บทความชุดนี้จะมีกี่ตอนก็ยังนึกไม่ออกเหมือนกัน Thinking smile แต่ก็น่าจะยาวในระดับนึงนะครับ ตอนแรกนี้จะขอพูดเรื่องที่ไม่ได้เกี่ยวข้องกับการเขียนโปรแกรมเท่าไหร่ก่อน เป็นการปูพื้นเรื่องน่ะครับ

...continue reading เรื่องวุ่น ๆ กับตัวหนังสือ – ตอนที่ 1 – Non Technical