2008-12-16(Tue)

OpenGL : First Window

ขั้นแรก เรามาสร้าง Window เปล่าๆ กันก่อนดีกว่า
เพื่อให้เข้าใจง่ายยึ่งขึ้น

149Code : Create Window
// Include ไฟล์ Header ของ glut เข้ามาเพื่อให้ใช้คำสั่งได้
#include

// ประกาศ Prototype Function เพื่อที่จะอ้างอิงใน main ได้โดยไม่ error
// ถ้าไม่ใช้วิธีนี้ ก็ต้องยกตัว function ทั้งก้อนมาใส่ไว้ก่อน main เพื่อให้ compiler รู้จัก
// ส่วนชื่อ จะตั้งเป็นอะไรก็ได้ เช่น display, draw, show ให้อ่านรู้เรื่องก็พอ
// function นี้ จะสร้างไว้สำหรับเก็บคำสั่งในการแสดงผล(ในภายภาคหน้า) ซึ่งในที่นี้ผมจะใช้ชื่อว่า draw
void draw(void);

// main ให้ประกาศ parameter ดังนี้ เพราะ argc และ argv จะถูกนำไปใช้ในบรรทัดต่อไป
int main(int argc, char **argv)
{
    // คำสั่งสำหรับเตรียมการของ glut ให้ใส่ไปตามนี้เลย
    glutInit(&argc, argv);

    // Display Mode จะมี Single Buffer(กินทรัพยากรเครื่องน้อยกว่า เพราะคำนวนการแสดงผลทีละ frame)
    // และ Double Buffer(ภาพ Smooth กว่า เพราะคำนวนผลของ frame ต่อไปรอไว้ แล้วสลับขึ้นมาใช้)
    // ถ้า Single Buffer ให้ใช้ parameter GLUT_SINGLE
    // ถ้า Double Buffer ให้ใช้ parameter GLUT_DOUBLE (☆แนะนำ ให้ใช้อันนี้)
    // ส่วน Mode สี ก็มี GLUT_RGB (Red, Green, Blue) และ GLUT_RGBA (Red, Green, Blue, Alpha)
    // ในตัวอย่างผมจะใช้ RGBA มันไปเลยละกัน (เผื่อไว้)
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);

    // คำสั่งในการสร้าง Window ส่วน parameter ที่ส่งให้ คือ Window Title
    // (ในที่นี้ผมจะตั้งชื่อว่า "OpenGL Project"
    glutCreateWindow("OpenGL Project");

    // คำสั่งสำหรับ run function การแสดงผล โดยส่ง parameter เข้าไปเป็นชื่อ function ที่ตั้งไว้ในตอนแรก
    // ที่ผมได้ตั้งไว้ก็คือ draw
    glutDisplayFunc(draw);

    // คำสั่งสำหรับสั่งให้ โปรแกรมทำการ วน loop ในการแสดงผลเรื่อยๆไปยัง frame ถัดไป
    glutMainLoop();
   
    return 0;
}

// function สำหรับ เรียกไป แสดงผล
void draw(void)
{
    // คำสั่งในการสลับ frame ถัดไปที่ได้รับการ buffer ไว้ ขึ้นมาแสดงผล
    // ในกรณีที่ใช้ Display Mode แบบ Double Buffer
    glutSwapBuffers();

    // ส่วนในกรณีที่แสดงผลทีละ frame แบบ Single Buffer จะใช้คำสั่ง ในบรรทัดต่อไปแทน
    // glFlush();
}


เท่านี้ก็จะได้กรอบ Window ขึ้นมาแล้ว ฟังดูเหมือนจะยาก แต่ที่จริงแล้วง่ายมาก
การเขียน comment อธิบาย เป็นภาษาไทย นี่ทำให้ดูรกขึ้นจมเลย

ตัว Code จริงๆก็มีอยู่แค่นี้เองครับ

#include

void draw(void);

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
    glutCreateWindow("OpenGL Project");

    glutDisplayFunc(draw);
    glutMainLoop();
   
    return 0;
}


void draw(void)
{  
    glutSwapBuffers();
}

เรื่องต่อไปจะสอนการตั้งค่า Window และ ทำพื้นหลัง
2008-12-14(Sun)

OpenGL : Getting Start OpenGL with C++

สามารถ Download Library ของ OpenGL ได้ที่ http://www.xmission.com/~nate/glut.html
โดยใน Tutorial ต่อจากนี้ ผมจะใช้ ไฟล์ version ดังต่อไปนี้ glut-3.7.6-bin.zip (117 KB)
หลังจากโหลดมาแล้ว ให้ทำการคลาย zip ออกมา จะมีไฟล์ดังต่อไปนี้
  • glut32.dll
  • glut32.lib
  • glut.def (ไฟล์นี้ไม่สำคัญ เป็น definition ปล่อยไป)
  • glut.h
  • README-win32.txt (วิธีการติดตั้งเป็นภาษาอังกฤษจะอยู่ข้างในนี้)
- ให้นำไฟล์ glut32.dll ไปไว้ที่ System32 ของ Windows (ปกติจะอยู่ที่ C:\WINDOWS\system32 )
- นำไฟล์ glut32.lib ไปไว้ที่ lib ของ Visual Studio หรือ Visual C++ Express
(ถ้าเป็น Visual Studio 2005 ปกติจะอยู่ที่ C:\Program Files\Microsoft Visual Studio 8\VC\lib
หากเป็น Visual Studio 2008 ก็จะเป็น Microsoft Visual Studio 9 )
★ไม่แนะนำ Visual C++ Express เท่าใหร่ เพราะ ปกติจะไม่มี library ชื่อ windows.h แถมมาให้ ทำให้เราต้องโหลด package เสริม มาติดตั้งเพิ่มอีก 400กว่า MB แถมมีขั้นตอนในการติดตั้งที่ยุ่งยาก)
- ไปที่ include ของ Visual Studio (ปกติจะอยู่ที่ C:\Program Files\Microsoft Visual Studio 8\VC\include) ให้สร้าง Folder ชื่อ GL และ นำไฟล์ glut.h ใส่ไว้ข้างใน

สรุป 
  • glut32.dll > C:\WINDOWS\system32
  • glut32.lib > C:\Program Files\Microsoft Visual Studio 8\VC\lib
  • glut.h        > C:\Program Files\Microsoft Visual Studio 8\VC\include\GL

- จบขั้นตอนการติดตั้ง -
---------------------------

-------------------------------------------
การสร้าง Project สำหรับ OpenGL

หลังจากเปิด Visual Studio ขึ้นมาแล้ว (ใน Tutorial จากนี้ ผมจะใช้ Visual Studio 2005 เป็นหลัก)
1. ไปที่ New > Project
2. เลือก Visual C++ > General > Empty Project
3. ตั้งชื่อ Project ในช่อง Name (ในตัวอย่างนี้ผมจะใช้ชื่อว่า OpenGL)
4. OK

-------------------------------------------
การตั้งค่า Project สำหรับ OpenGL

1. ไปที่ Project Property ทำได้ 2 วิธี
 A) ไปที่ หน้าต่าง Solution Explorer  (หากถูกปิดอยู่ให้เรียกออกมาจาก View > Solution Explorer หรือ กด Ctrl+Alt+L)  จากนั้น Clickขวาที่ ชื่อ Project(บรรทัดที่2) เลือก Properties
 B) ไปที่ menu Project > Properties

2. ไปที่ Configuration Properties > Linker > Input
3. ตรงช่องแรกทางขวามือ ที่เขียนว่า Additional Dependencies ให้พิมพ์บรรทัดต่อไปนี้ใส่ลงไป
opengl32.lib glu32.lib glut32.lib
4. OK

--------------------------------------------
การสร้าง Code File สำหรับ Project
1. ใน Solution Explorer ใน Project ของเรา จะเห็น รูป Folder 3 อัน คือ
 - Header Files
 - Resource Files
 - Source Files
2. Right Click ที่ Source Files
3. Add > New Item...
4. Visual C++ > Code > C++ File (.cpp)
5. ตั้งชื่อไฟล์ ตรง Name: (ในตัวอย่างนี้ผมจะใช้ชื่อว่า Program)
6. Add
เท่านี้เราก็จะได้ ไฟล์ .cpp มา
ซึ่งเราจะเขียน code ลงไปในบทถัดไป
2008-10-28(Tue)

How to: Draw Text

69Essential : ★★★★★

59 Create SpriteFont File :
1) Right Click on 「Content」 in the Solution Explorer
2) Select : Add > New Item...
3) Name your File
4) Click 「Add」
149 Note : If your File name same As TrueType Font name
it will Automatic set your FontName to a TrueType Font name
else you can Change Manually in XML Code.

Create SpriteFont File

508Core Code : SpriteFont Declaration
154In Method : Constructor
            SpriteFont font;


508Core Code : Load Font
154In Method : LoadContent()
149 Note : font = Content.Load<SpriteFont>("Font FileName");
            font = Content.Load<SpriteFont>("Arial");


508Core Code : SpriteBatch (Draw 2D)
154In Method : Draw()
149 Note : EVERY 2D Object MUST Draw Between spriteBatch.Begin() & spriteBatch.End() 
            //Begin SpriteBatch
            spriteBatch.Begin();

            // ▽ Insert What to Draw HERE ▽//           

            //End SpriteBatch
            spriteBatch.End();

508Core Code : Draw SpriteFont
154In Method : Draw()
149 Note : Put This Code Between spriteBatch.Begin() & spriteBatch.End() 
            spriteBatch.DrawString(font, "Font Testing", new Vector2(30, 25), Color.White);
141 Detail : Use String \n for 「New Line」


510 Code Example :
149 Note :

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TechnicalAlchemist
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        //SpriteFont Declaration
        SpriteFont font;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            //Change Window Title
            Window.Title = "Technical Alchemist ^^";

            //Resolution Setting
            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 768;
            graphics.ApplyChanges();

        }

        protected override void Initialize()
        {

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            //Load Font
            font = Content.Load<SpriteFont>("Arial");
        }

        protected override void UnloadContent()
        {

        }
       
        protected override void Update(GameTime gameTime)
        {
            //Exit Game when Pressed ESC Key
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                Exit();
            }
           
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            //Begin SpriteBatch
            spriteBatch.Begin();

            //Draw Text
            spriteBatch.DrawString(font, "Font Testing", new Vector2(30, 25), Color.White);

            //End SpriteBatch
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

2008-10-28(Tue)

How to: Change Background Color

69Essential : ★★★★

508Core Code : Set Background Color

graphics.GraphicsDevice.Clear(Color.CornflowerBlue);


510Example : Change Code in Draw() Method
149 Note : I'll use 「Color.MediumAquamarine」 in this Example.

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TechnicalAlchemist
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            //Change Window Title
            Window.Title = "Technical Alchemist ^^";

            //Resolution Setting
            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 768;
            graphics.ApplyChanges();

        }

        protected override void Initialize()
        {

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
        }

        protected override void UnloadContent()
        {

        }
       
        protected override void Update(GameTime gameTime)
        {
            //Exit Game when Pressed ESC Key
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                Exit();
            }
           
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            //Set Background Color
            graphics.GraphicsDevice.Clear(Color.MediumAquamarine);


            base.Draw(gameTime);
        }
    }
}

2008-10-27(Mon)

How to: Change Resolution

69Essential : ★★★★★

508Core Code : Resolution Setting ( Change Back Buffer )

            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 768;


508Core Code : Apply Changes

            graphics.ApplyChanges();

149 Note : 55 NO NEED to 「Apply Changes」 if Set Resolution in 「Constructor」
      But   2 MUST 「Apply Changes」 if Set Resolution in Other Method (e.g.  Initialize(), LoadContent(), UnloadContent(), Update(), Draw() )

510Example : Put Code in Update() Method

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TechnicalAlchemist
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            //Change Window Title
            Window.Title = "Technical Alchemist ^^";
        }

        protected override void Initialize()
        {
            //Resolution Setting
            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 768;

            //Apply Changes
            graphics.ApplyChanges();

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
        }

        protected override void UnloadContent()
        {

        }
        
        protected override void Update(GameTime gameTime)
        {
            //Exit Game when Pressed ESC Key
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                Exit();
            }
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            base.Draw(gameTime);
        }
    }
}

Calendar
12 | 2012/01 | 02
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
Latest Entries
Category
Monthly Archive
Latest Comments
Latest Trackbacks
RSS
E-Mail

name:
mail address:
subject:
body:

Profile

Reiki

Author:Reiki
3D Artist, Game Programmer

Search Form
Link
Technical Alchemist
QR
Add Friend Form

Add this person to blog friend

Blog Friend List
FC2 Counter