Bu Blogda Ara

5 Aralık 2010 Pazar

Drawing a Text on Screen in an OpenGL Application


Drawing a text on screen is a very general problem when you first start OpenGL. Conversely, it is simple to implement. I tried to make it possible with a little function as I show in the video above. Please note that it is required GLUT library to generate fonts. Do not forget to include to your project. I used SDL to manage Windows but it is optional for you.

Here is the code:


#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <Windows.h>
#include <SDL.h>
#include <gl\GL.h>
#include <gl\GLU.h>
#include <glut.h>
#include <math.h>
#include <cstring>



#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")


/*
Drawing text 2D screen.
*/
void drawText(const char *text, int length, int x, int y){
glMatrixMode(GL_PROJECTION); // change the current matrix to PROJECTION
double matrix[16]; // allocate 16-byte in memory (thanks to BlueByteGames about memory-leak warning comment on YouTube)
glGetDoublev(GL_PROJECTION_MATRIX, matrix); // get the values from PROJECTION matrix to local variable
glLoadIdentity(); // reset PROJECTION matrix to identity matrix
glOrtho(0, 800, 0, 600, -5, 5); // orthographic perspective
glMatrixMode(GL_MODELVIEW); // change current matrix to MODELVIDE matrix again
glLoadIdentity(); // reset it to identity matrix
glPushMatrix(); // push current state of MODELVIEW matrix to stack
glLoadIdentity(); // reset it again. (may not be required, but it my convention
glRasterPos2i(x, y); // raster position in 2D
for(int i=0; i<length; i++){
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, (int)text[i]); // generation of characters in our text with 9 by 15 GLU font
}
glPopMatrix(); // get MODELVIEW matrix value from stack
glMatrixMode(GL_PROJECTION); // change current matrix mode to PROJECTION
glLoadMatrixd(matrix); // reset
glMatrixMode(GL_MODELVIEW); // change current matrix mode to MODELVIEW
}

void DrawScreen(SDL_Surface* screen, int h)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

gluLookAt(0,0,-10, 0,0, 3, 0, 1, 0);

glColor3f(1,0,0);

glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glEnd();

std::string text;
text = "This is a simple text.";
glColor3f(0, 1, 0);
drawText(text.data(), text.size(), 50, 200);


SDL_GL_SwapBuffers();
}

static void reshape(int width, int height)
{
GLfloat h = (GLfloat) height / (GLfloat) width;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 45.0, h, 1.0, 1000.0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

SDL_Surface *surface;
int main(int argc, char **argv)
{

if (SDL_Init(SDL_INIT_VIDEO || SDL_INIT_AUDIO)<0)
{
return 1;
}

surface = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL | SDL_RESIZABLE | SDL_DOUBLEBUF);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);


glLineWidth(1.5f);


glMatrixMode(GL_MODELVIEW);

reshape(800,600);
SDL_Event event;

int keypress = 0;
int h=0;

while(!keypress)
{

while(SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
keypress = 1;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym){
case SDLK_LEFT:

break;
case SDLK_RIGHT:

break;
case SDLK_UP:

break;
case SDLK_DOWN:

break;
default:
break;
}
default:
break;
}

}
DrawScreen(surface,h++);
}

SDL_Quit();
return 0;
}

20 Kasım 2010 Cumartesi

Paralel Programlama ile PI Sayısının Hesaplanması

PI sayısı küçük yaşımdan beri bana hep gizemli gelmiştir. İrrasyonel yapıda olduğu için tam değeri hesaplanamayışı, bir çok matematiksel ve geometrik hesabın temelini oluşturması, çok eski medeniyetler tarafından kullanılmış olması insanın ister istemez ilgisini çekiyor. İnternetteki bir tanıma göre (bkz: wikipedia) "çapı 1 olan dairenin çevre uzunluğu" dur PI sayısı.

(bkz: http://tr.wikipedia.org/wiki/Dosya:Pi-unrolled-720.gif)


PI sayısının önemi hakkında daha fazla yazıp çizmek isterdim fakat bu yazının konusu dışında kalmaktadır. Asıl konumuz bu sayının yaklaşık değerini Paralel Programlama yöntemlerini kullanarak nasıl hesaplarız. Yaklaşık değerini dedim çünkü tam değerini hesaplayamayacağımızı artık biliyoruz. :) Bu sayı için hesaplayacağımız basamak sayısı yapmak istediğimiz işin büyüklüğüyle doğru orantılı. Arka bahçemizdeki havuzunuz kaç m^3 su aldığını hesaplamamız için 3.1415 değeri yeterken, Ay'a bir araç göndermek isteyen NASA mühendisleri için 3.1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196 4428810975 6659334461 2847564823 3786783165 2712019091 4564856692 3460348610 4543266482 1339360726 0249141273 7245870066 0631558817 4881520920 9628292540 9171536436 7892590360 0113305305 4882046652 1384146951 9415116094 3305727036 5759591953 0921861173 8193261179 3105118548 0744623799 6274956735 1885752724 8912279381 8301194912 9833673362 4406566430 8602139494 6395224737 1907021798 6094370277 0539217176 2931767523 8467481846 7669405132 0005681271 4526356082 7785771342 7577896091 7363717872 1468440901 2249534301 4654958537 1050792279 6892589235 4201995611 2129021960 8640344181 5981362977 4771309960 5187072113 4999999837 2978049951 0597317328 1609631859 5024459455 3469083026 4252230825 3344685035 2619311881 7101000313 7838752886 5875332083 8142061717 7669147303 5982534904 2875546873 1159562863 8823537875 9375195778 1857780532 1712268066 1300192787 6611195909 2164201989 3809525720 1065485863 2788659361 5338182796 8230301952 0353018529 6899577362 2599413891 2497217752 8347913151 5574857242 4541506959 5082953311 6861727855 8890750983 8175463746 4939319255 0604009277 0167113900 9848824012 8583616035 6370766010 4710181942 9555961989 4676783744 9448255379 7747268471 0404753464 6208046684 2590694912 9331367702 8989152104 7521620569 6602405803 8150193511 2533824300 3558764024 7496473263 9141992726 0426992279 6782354781 6360093417 2164121992 4586315030 2861829745 5570674983 8505494588 5869269956 9092721079 7509302955 3211653449 8720275596 0236480665 4991198818 3479775356 6369807426 5425278625 5181841757 4672890977 7727938000 8164706001 6145249192 1732172147 7235014144 1973568548 1613611573 5255213347 5741849468 4385233239 0739414333 4547762416 8625189835 6948556209 9219222184 2725502542 5688767179 0494601653 4668049886 2723279178 6085784383 8279679766 8145410095 3883786360 9506800642 2512520511 7392984896 0841284886 2694560424 1965285022 2106611863 0674427862 2039194945 0471237137 8696095636 4371917287 4677646575 7396241389 0865832645 9958133904 7802759009 değeri yetersiz ya da yanıltıcı olabilir. Bu yüzden sıradışı ihtiyaçlar için (fezaya mekik göndermek gibi) sıradışı çözümler sunmamız gerekmektedir. Bir gün NASA mühendisleri için PI sayısı hesaplarmıyız bilemiyorum fakat gelecekte çok fazla paralel işlem bizleri bekliyor. Şimdiden kendimizi hazırlamalıyız.

Lafı fazla dolandırmadan işe koyulalım. İlk PI hesabımızı Monte Carlo yöntemiyle yapacağız. Bu yöntem oldukça basit bir olasılık hesabına dayanmaktadır.



Bu olasılık hesabını yapmak için C++ programlama dili üzerinden openMP kütüphanesini kullandım. Paylaşımlı bellek üzerinden paralel programlama yapmak için geliştirilmiş olan bu kütüphane kullanması oldukça basittir. Mevcut kodunuza hiç dokunmadan (elbetteki paylaşımlı bellek paralel program mantığı güdülerek yazılmış kod olamalı) doğrudan programınızı paralel çalıştırabilirsiniz. Bu yazacağımız program dağıtık mimariler için değil tek bir süper bilgisayar için programlanmıştır. Makine üzerindeki çekirdek sayısıyla doğru orantılı olarak performans artışı sağlanacaktır.

Programımızı yazmadan önce Visual Studio 2010 üzerinden projemizin openMP desteğini açalım. Project -> Properties ...


(DÜZELTME)








Şimdi programımızı yazalım. Programda açıklamak istediğim tüm noktaları yorum satırı olarak ekledim. Bir göz atalım sonra sonuçları değerlendirelim.


/*
Monte Carlo yöntemiyle PI sayısının yaklaşık değerinin hesaplanması.

C++ / openMP

Ramazan Bellek - Kasım 2010
*/

#include <iostream>
#include <ctime>
#include <math.h>

#define MAX_ITERATION 1000000 // tekrarlama sayısı
#define r 500 // yarıçap
#define R r*2+1 // çap + 1

int main(int argc, char **argv)
{
srand(time(0));
clock_t start = clock();

bool iceride[MAX_ITERATION]; // doğruluk tablomuz
double x,y;

/*
openMP ile birbirinden bağımsız olan hesaplama kısmını işlemciye paralel olarak işletiyoruz.
x ve y değişkenleri her bir iş parçacığı için kişisel olarak tanımlandı, böylelikle bir iş parçacığı
diğerinin konum bilgisini görememektedir. Doğruluk tablosunu belirten değişkeni ise ortak olarak
kullanacaklardır.
*/
#pragma omp parallel for private(x,y) shared(iceride)
for(int i=0;i<MAX_ITERATION; i++)
{
// uzayda bir noktayı (sözde) keyfi seçiyoruz.
x = rand()%R;
y = rand()%R;

double fark = sqrt(pow(x-r,2)+pow(y-r,2)); // seçtiğimiz noktanın dairenin merkezine olan uzaklığını alıyoruz.

if (fark<=r) // eğer bu uzaklık dairenin yarıçapından küçük ya da eşit ise nokta dairenin içerindedir.
iceride[i]=true;
else
iceride[i]=false;
}

long toplamIceride = 0;
// daire içerisine düşen toplam sayı
for(int i=0;i<MAX_ITERATION; i++){
if (iceride[i]==true)
toplamIceride++;
}

/*
daire_icine_dusen/toplam = (pi*r^2)/(4*r^2)
=> pi = 4 * daire_icine_dusen/toplam
*/
std::cout<<"PI ~= "<<4*(double)toplamIceride/MAX_ITERATION<<std::endl;

printf("Gecen Sure: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
system("pause");
return 0;
}


Programımızı çalıştırıyoruz.



Sonuç aslında pek istediğim gibi çıkmadı. Beklentim en azından ilk 4 basamağı (3.1415) bulmak üzereydi. İterasyonları arttırarak tekrar denenebilir, ayrıca burada ürettiğimiz rastgele sayılar sözde olduğu için bize tam bir sonuç vermesi beklenemez. İterasyonu arttırarak işlemcinin çekirdeklerindeki değişimi göstermek istiyorum.



Gördüğünüz gibi PI sayısını bir süper bilgisayarda nasıl hesaplayacağımızı basit olarak da olsa görmüş olduk. Daha detaylı görsel uygulama için http://www.eveandersson.com/pi/monte-carlo-demo adresindenki java applete göz atabilirler.

Bir sonraki paralel programlama yazımda paylaşımsız bellekli dağıtık mimari kullaranak PI sayısını hespalamaya çalışacağım. Küçük bir bilgisayar kümesi kurarak dev işlemleri basitleştirmeye çalışacağız. Gelecekteki bir bilgisayar ordusunun komutanı olmanız ümidiyle. Hoşçakalın...

15 Kasım 2010 Pazartesi

Tic Tac Toe Oyunu - Yapay Zeka - MiniMax Algo.

Yapay zeka konusuna ilk girişi klasik Minimax algoritmasıyla yapıyorum. Algoritma çok basit ve etkili bir yöntem kullanmaktadır. Oyuncu bir hamle yaptıktan sonra diğer tüm oyunları oynayarak bilgisayarın en az kaybettiği en çok kazandığı hamle tespit edilmiş olur. Uygulamayı Python dilinde gerçeklemeye çalıştım. Doğası itibariyle %100 nesne yönelimli programlandı. Görsel arayüz için OpenGL (pyOpenGL) ve GLUT kütüphanelerini kullandım. Algoritma için daha detaylı bilgiyi http://en.wikipedia.org/wiki/Minimax adresinden edinebilirsiniz. İsterseniz programa ve kodların açıklamasına şöyle bir göz atalım, ardından kaynak kodu vereyim.












# -*- coding: cp1254 -*-


"""
MiniMax algoritmasını kullanarak Tic Tac Toe oyununun gerçeklenmesi

Sakarya Üniversitesi Bilgisayar Mühendisliği Bölümü
Yapay Zeka Dersi Ödevi

Ramazan Bellek - Ekim 2010


"""


from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import time
import math
import copy
from Tkinter import *


# MiniMax algoritmasını gerçekleyen sınıf
class MiniMax:
mevcutDurum = [[]]
def __init__(self, mevcutDurum): # yapılandırıcı metod
self.mevcutDurum = copy.deepcopy(mevcutDurum)

# bilgisayarın bir sonraki yapacağı en mantıklı hareketi belirler
def sonrakiHamleyiHesapla(self):
tahta = self.mevcutDurum
max = [[0 for satir in range(3)] for sutun in range(3)]
for x in range(3):
for y in range(3):
if tahta[x][y] == 0:
tahta[x][y] = 1 # boş alana hamle yap
max[x][y] = self.__tara(tahta, 1) # alt ağaçları tara
tahta[x][y] = 0 # tarama bitince yapılan hamle geri alınır
else:
max[x][y] = -99
sonuc = -99
donusDegeri = [0,0]
for x in range(3):
for y in range(3):
if max[x][y]>sonuc:
sonuc=max[x][y]
donusDegeri = [x, y]
return donusDegeri

# alt oyun ağaçlarını tarar
def __tara(self, t, s):
tahta = copy.deepcopy(t)
sonEl = copy.deepcopy(s)
toplam = [[0 for satir in range(3)] for sutun in range(3)]
for x in range(3):
for y in range(3):
if tahta[x][y] == 0:
tahta[x][y] = sonEl*-1
kontrolSonucu = Hakem.kontrolEt(tahta)
if kontrolSonucu != 5: # -> tahta henüz dolu değil!
return kontrolSonucu
toplam[x][y] = self.__tara(tahta, sonEl*-1)
tahta[x][y] = 0
if sonEl == 1:
return self.Min(toplam)
else:
return self.Max(toplam)

# Katardaki azami değeri tespit eder.
def Max(self, t):
tahta = copy.deepcopy(t)
deger = -99
for x in range(3):
for y in range(3):
if tahta[x][y]>deger:
deger = tahta[x][y]
return deger

# Katardaki asgari değeri tespit eder.
def Min(self, t):
tahta = copy.deepcopy(t)
deger = 99
for x in range(3):
for y in range(3):
if tahta[x][y] deger = tahta[x][y]
return deger

class Hakem:
@staticmethod
def bosMu(t):
tahta = copy.deepcopy(t)
for x in range(3):
for y in range(3):
if tahta[x][y] == 0:
return True
return False
@staticmethod
def kontrolEt(t):
tahta = copy.deepcopy(t)

# oyuncu hamleleri --------------

# yatay kontrol --
if tahta[0][0] == tahta[1][0] == tahta[2][0] == -1:
return -1
elif tahta[0][1] == tahta[1][1] == tahta[2][1] == -1:
return -1
elif tahta[0][2] == tahta[1][2] == tahta[2][2] == -1:
return -1
# ----------------

# dikey kontrol --
elif tahta[0][0] == tahta[0][1] == tahta[0][2] == -1:
return -1
elif tahta[1][0] == tahta[1][1] == tahta[1][2] == -1:
return -1
elif tahta[2][0] == tahta[2][1] == tahta[2][2] == -1:
return -1
# ----------------

# çapraz kontrol --
elif tahta[0][0] == tahta[1][1] == tahta[2][2] == -1:
return -1
elif tahta[2][0] == tahta[1][1] == tahta[0][2] == -1:
return -1
# -----------------

# ------------------------------------

# Bilgisayar hamleleri --------------

# yatay kontrol --
if tahta[0][0] == tahta[1][0] == tahta[2][0] == 1:
return 1
elif tahta[0][1] == tahta[1][1] == tahta[2][1] == 1:
return 1
elif tahta[0][2] == tahta[1][2] == tahta[2][2] == 1:
return 1
# ----------------

# dikey kontrol --
elif tahta[0][0] == tahta[0][1] == tahta[0][2] == 1:
return 1
elif tahta[1][0] == tahta[1][1] == tahta[1][2] == 1:
return 1
elif tahta[2][0] == tahta[2][1] == tahta[2][2] == 1:
return 1
# ----------------

# çapraz kontrol --
elif tahta[0][0] == tahta[1][1] == tahta[2][2] == 1:
return 1
elif tahta[2][0] == tahta[1][1] == tahta[0][2] == 1:
return 1
# -----------------

# ------------------------------------

# Eşitlik durumu
if Hakem.bosMu(tahta) == False:
return 0
return 5 # -> tahta henüz dolu değil!

class Tahta:
"""Oyun tahtası sınıfı"""
tahta = [ [0 for satir in range(3)] for sutun in range(3)]
siraBilgisayarda = False
oyunBitti = False

def __init__(self):
oyunBitti = False
self.ilkDefa = True

def ciz(self):
if self.oyunBitti == True:
glColor(0.9, 0.6, 0.1)
drawText("Oyun bitti... :|", 10 ,5 ,250, 250)
elif self.ilkDefa == True:
glColor(0.9, 0.6, 0.1)
drawText("Oynamaya hazirim, lütfen bir hamle yapiniz... :)", 10 ,5 ,250, 250)
else:
glColor(0.9, 0.6, 0.1)
drawText("Sizin siraniz ?", 10 ,5 ,250, 250)

if self.ilkDefa == True:
self.ilkDefa = False
Tahta.cerceveCiz()
self.__oyunCiz()


@staticmethod
def cerceveCiz():
glLineWidth(2.5)
glColor(0.0, 0.0, 1.0)
glBegin(GL_LINES)

# dış çerçeve ------------
glVertex(-0.9, 0.9, 0.0)
glVertex(0.9, 0.9, 0.0)
glVertex(-0.9, 0.9, 0.0)
glVertex(-0.9, -0.9, 0.0)
glVertex(-0.9, -0.9, 0.0)
glVertex(0.9, -0.9, 0.0)
glVertex(0.9, -0.9, 0.0)
glVertex(0.9, 0.9, 0.0)
# -------------------------

# ızgaralar ---------------
glVertex(-0.3, -0.9, 0.0)
glVertex(-0.3, 0.9, 0.0)
glVertex(0.3, -0.9, 0.0)
glVertex(0.3, 0.9, 0.0)
glVertex(-0.9, -0.3, 0.0)
glVertex(0.9, -0.3, 0.0)
glVertex(-0.9, 0.3, 0.0)
glVertex(0.9, 0.3, 0.0)
# -------------------------
glEnd()

def __xCiz(self, x, y):
x =0.6*x-0.6
y =-1*(0.6*y-0.6)
glLineWidth(8.5)
glColor(0.0, 1.0, 0.0)
glBegin(GL_LINES)
glVertex(x-0.175, y-0.175)
glVertex(x+0.175, y+0.175)
glVertex(x-0.175, y+0.175)
glVertex(x+0.175, y-0.175)
glEnd()

def __oCiz(self, x, y):
x =0.6*x-0.6
y =-1*(0.6*y-0.6)
glLineWidth(1.5)
glColor(1.0, 0.0, 0.0)
glPushMatrix()
glTranslate(x, y, 0.0)
glBegin(GL_LINES)
for i in range(0, 1080):
glVertex(math.sin(i)*0.2,math.cos(i)*0.2)
glEnd()
glPopMatrix()

def __oyunCiz(self):
for x in range(3):
for y in range(3):
if self.tahta[x][y] == -1:
self.__xCiz(x, y)
elif self.tahta[x][y] == 1:
self.__oCiz(x, y)

''' tüm hamleler bu metod üzerinden gerçekleştirilir.
kullanıcı girişleri bu metoda yönlendirilerek kullanıcının hamle yapması
sağlanırken, her hamleden sonra öz yinelemeli olarak bilgisayar kendi hamlesini yapar.
Yapacağı hamleyi MiniMax algoritmasınını kullanarak tespit etmeye çalışır.
'''
def oyna(self, x, y):
try:
if self.oyunBitti == True:
## Mesaj.msj("Oyun bittiği için hamle yapamazsınız.","Üzgünüm... :(")
return
if x not in range(40, 760):
return
if y not in range(30, 560):
return
x = (x-40)/240
y = (y-30)/176
if self.tahta[x][y] == 0:
if self.siraBilgisayarda:
self.siraBilgisayarda = ~self.siraBilgisayarda
self.tahta[x][y] = 1
self.ciz()
glFlush ()
glutSwapBuffers()
self.__kontrolEt()
else:
self.siraBilgisayarda = ~self.siraBilgisayarda
self.tahta[x][y] = -1
self.ciz()
glFlush ()
glutSwapBuffers()
self.__kontrolEt()
if self.oyunBitti == True:
return
mm = MiniMax(self.tahta)
time.sleep(0.5)
xy = mm.sonrakiHamleyiHesapla()
self.oyna(xy[0]*240+40, xy[1]*176+30)
glutPostRedisplay()
except:
print "Beklenmeyen bir hata meydana geldi. Lütfen tekrar deneyiniz."
raise

def __kontrolEt(self):
durum = Hakem.kontrolEt(self.tahta)
if durum == 0:
self.oyunBitti = True
Mesaj.msj("Berabere bitti!", "Eşitlik durumu")
glEnable(GL_LIGHTING)
glutPostRedisplay()
return

# Bilgisayarın hamleleri --------------
mesaj = "Bilgisayar kazandı! :/\nBiraz daha dikkatli olmalısınız..."
if durum == 1:
self.oyunBitti = True
Mesaj.msj(mesaj, "Oyun bitti...")
glEnable(GL_LIGHTING)
glutPostRedisplay()
return
# ------------------------------------

# oyuncu hamleleri --------------
mesaj = "Tebrikler, siz kazandınız... :)"
if durum == -1:
self.oyunBitti = True
Mesaj.msj(mesaj, "Oyun bitti...")
glEnable(GL_LIGHTING)
glutPostRedisplay()
return
# ------------------------------------
if durum == 5: # -> tahta henüz dolu değil
return

# Mesaj sınıfı ----
class Mesaj:
root = None
def __init__(self, root):
self.root = root
@staticmethod
def msj(yazi, baslik):
root = Tk()
root.title(unicode(baslik, encoding="cp1254"))
root.withdraw()
mesaj = Mesaj(root)
mesaj.top = Toplevel(root)
Label(mesaj.top, text=unicode(yazi, encoding="cp1254")).pack()
Button(mesaj.top, text="OK", command=mesaj.tamam).pack(pady=5)
root.wait_window(mesaj.top) # pencere Tamam komutu verene kadar bekler.
root.destroy()
def tamam(self):
self.top.destroy()
# -----------------

# Yazı yazma fonksiyonu (pyOpenGL - örneğinden alınmıştır!)
def drawText( value, x,y, windowHeight, windowWidth, step = 18 ):
value = unicode(value, encoding="cp1254")
glMatrixMode(GL_PROJECTION);
matrix = glGetDouble(GL_PROJECTION_MATRIX)
glLoadIdentity();
glOrtho(0.0, windowHeight or 32, 0.0, windowWidth or 32, -1.0, 1.0)
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRasterPos2i(x, y);
lines = 0
for character in value:
if character == '\n':
glRasterPos2i(x, y-(lines*18))
else:
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ord(character));
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(matrix)
glMatrixMode(GL_MODELVIEW);
# --------------------------------

# uygulama giriş fonsiyonları ---------------

resX,resY = (800,600 ) # ekran çözünürlüğü
oyunTahtasi = Tahta() # tahta sınıfı

def goster( ): # openGL render fonksiyonu
glutSetWindow(window);
glClearColor (1.0, 1.0, 1.0, 1.0)
glClear (GL_COLOR_BUFFER_BIT)
oyunTahtasi.ciz()
glFlush ()
glutSwapBuffers()

def ayarla():
''' yumuşak çizim '''
glShadeModel(GL_SMOOTH)
glDisable(GL_LIGHTING)



def fare(button, state, x, y):
if button == 0 and state == 1:
oyunTahtasi.oyna(x, y)


if __name__ == "__main__":
glutInit([])
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)

glutInitWindowSize(resX, resY) # pencere genişliği
glutInitWindowPosition(0, 0)
window = glutCreateWindow("Tic Tac Toe Oyunu / MiniMax Yapay Zeka Uygulaması - Ramazan Bellek | Ekim 2010")
glutMouseFunc(fare)
ayarla()


glutDisplayFunc(goster)
glutMainLoop()

30 Ekim 2010 Cumartesi

Game Engine Programming



3 Boyutlu Oyun Motoru geliştirme seminerim önümüzdeki Salı günü (2 Kasım 2010) başlayacağını büyük bir mutlulukla duyurmak isterim :) Sau Bilgisayar Topluluğu bünyesinde gerçekleştilecek olan organizasyon için zaman 13:00~15:00 saatleri arası (D8 binası - sınıf henüz bana bildirilmedi) şeklinde düşünüldü. Ders yoğunluğuna bakarak en uygun zaman seçilmeye çalışıldı. Bu aralıkta dersi olan arkadaşlardan özür diliyorum. Eğer bir aksilik çıkmaz ise her salı bu seminerler düzenlenecek. Seminerlerle ilgili her türlü görüş ve eleştirilerinizi yorum olarak bu girdinin peşine bekliyorum.

Salı günü görüşmek üzere efendim. :)




-------02.11.2010------------------------------
İlk eğitimin başarılı geçtiğine inanıyorum. Katılan tüm arkadaşlara teşekkür ederim.
1. hafta sunum dosyasını buraya tıklayarak indirebilirsiniz.

Eğitimin bundan sonraki haftalarında tüm etkinliğin kameraya çekilmesi düşünülüyor. Ben de faydalı olacağına inanıyorum.

Haftaya aynı saatte görüşmek üzere.
-----------------------------------------------

-------09.11.2010------------------------------
İkinci hafta eğitim sunumları için:
sunum2
sunum3

sunumda kullanılan videolar:
Blender
Cry Engine 3
UDK

ayrıca sunumun bir kısmı video kameraya çekilmiştir. Görüntüler henüz elime ulaşmadı. Çekim yapan arkadaştan elde ettiğim zaman paylaşacağım.

Katılan herkese teşekkür ederim. Bayramdan sonraki hafta görüşmek üzere.

-------23.11.2010---------------------------------------
sunum4

Eğitim Videoları (YouTube)


Makine dilinde derleyicisiz yazdığımız uygulama.


--------------------------------------------------------



About this playlist

9 videos
Total length: 1 hour, 26 minutes

Description: Sakarya Üniversitesi Bilgisayar Mühendisliği 3 Boyutlu Oyun Motoru Programlama Seminerleri 5. Oturumu
Oturum Konusu: OpenGL
Toplam Uzunluk: 01:30:30

15 Ekim 2010 Cuma

13. MÜSİAD Fuarı / CNR EXPO

2007 yılında Biltronik bilgi teknolojileri yarışmasında ödül kazandığım projemi tanıtmak üzere CNR EXPO 13. MÜSİAD Fuarı'nda kendim için ayrılan standa bulundum. Projemin gelişimini durdurmuş olsam da, standın arkasında olmanın zorluklarını anlama açısından faydalı bir deneyim olduğunu düşünyorum.







18 Eylül 2010 Cumartesi

Java ile Nesneleri Dosyaya Kaydetme ve Okuma (Serialization)

Nesne yönelimli programlamada bellekte yüklü nesnelerin dosyaya kaydedilmesi ve tekrar dosyadan okunarak belleğe yüklenmesi olayına Serialization (Serileştirme olarak tercüme edilebilir) denmektedir.


Örneğimize geçmeden önce bu yöntem ile neler yapabileceğimizi değerlendirelim. Geliştirdiğimiz programlarda tüm işlemleri nesneler üzerinden gerçekleştiririz. Bazı durumlarda uygulamamızda kullanacağımız bilgileri bir dosya üzerinde saklamak isteyebiliriz. Bu noktada aklımıza veritabanı sistemleri gelebilir, fakat burada bahsettiğimiz veriler programın mantıksal verileri olduğu için genelde büyük boyutta olmazlar. Aynı zamanda nesnelerimizi veritabanında da tutabiliriz. Unutmamız gereken nokta Serialization dediğimiz olay nesnelerin hafızadaki yapısını ikili (binary) olarak saklamaktır. Neler yapılabilir sorusuna çok çeşitli cevaplar veribilir benim aklıma gelen şu başlıklar:
- Uygulamanın ayarlarının kaydedilmesi
- Basit bir veritabanı olarak kullanılması
- Programın çökmesi durumunda en son tutarlı yerden devam etmesi için hafızanın kaydedilmesi...

Normalde düşündüğümüz zaman bir nesneyi diskte saklamak çok külfetli bir iştir. Nesnenin tüm bilgilerini tek tek toplayıp bir sıraya koyacaksınız, ardından bunları karıştırmadan ve atlamadan (null değişkenler olabilir, ya da String benzeri dinamik genişleyen generic yapılar olabilir) doğru bir şekilde yazmalısınız. Okuma olayına hiç girmiyorum zaten. Ayrıca her nesnenin iç yapısı farklı olacaktır!

Peki hafızadan direk BYTE dizisi olarak diske yazmak? Java dilinde hafızaya direk erişimimiz olmadığı (işaretçilerin olamaması) için normal şartlar altında mümkün olmaması lazım. Fakat Java bize bu işlemi çok kolay bir şekilde yapacak bir imkan sağlamaktadır.

Java'da yazılan tüm nesneler Serializable arayüzünden (interface) kalıtım aldığı sürece sorunsuz bir şekilde diske yazılabilmektedir. Aynı rahatlıkla diskten okunabilmektedir. Bunun için özel olarak hazırlanmış yazan ve okuyan sınıfları kullanmaktadır.

Lafı fazla dolandırmadan örneğimize geçelim. Yorum satırlarını yeterli gördüğüm için tekrardan açıklama gereği duymadım.



/*
* Öğrenci Sınıfı
* Ogrenci.java
*/

package rbellek.blogspot.com;

import java.io.Serializable;

/**
*
* @author Ramazan
*/
public class Ogrenci implements Serializable {

private String isim;

public String getIsim() {
return isim;
}

public void setIsim(String isim) {
this.isim = isim;
}
}


/*
* Serilazation Örnek
* Main.java
*/
package rbellek.blogspot.com;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author Ramazan
*/
public class Main {

public static void main(String[] args) {
Ogrenci o1 = new Ogrenci(); // Yeni bir öğrenci nesnesi oluşturalım.
o1.setIsim("Ahmet"); // İsmini verelim.
System.out.println(o1.getIsim()); // Test edelim.
try {
// Nesneyi dosyaya kaydedelim.
FileOutputStream yazmac = new FileOutputStream("Ogrenci1.nesne"); // Dosyaya veri aktarım akışı nesnesi oluşturalım.
ObjectOutputStream nesneYazmac = new ObjectOutputStream(yazmac); // Nesneleri veri akışlarına yazmaya yarayan nesneyi oluşturalım.
nesneYazmac.writeObject(o1); // Öğrenci nesnemizi dosyaya yazıyoruz.
nesneYazmac.close(); // akışı kapatalım.
} catch (FileNotFoundException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

o1.setIsim("Mehmet"); // Öğrenci nesnemizin adını değiştirelim.
System.out.println(o1.getIsim()); // Test edelim.

Ogrenci o2 = null; // Başka bir öğrenci nesnesi referansı. (Henüz bir nesne oluşturmadık!)

try {
FileInputStream okuyucu = new FileInputStream("Ogrenci1.nesne"); // Dosyadan veri alan akış nesnesi.
ObjectInputStream nesneOkuyucu = new ObjectInputStream(okuyucu); // Dosyada kayıtlı nesneleri okuyan nesne.
o2 = (Ogrenci) nesneOkuyucu.readObject(); // Öğrenci nesnemizi okuyalım.
nesneOkuyucu.close(); // akışı kapatalım.
} catch (FileNotFoundException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}

System.out.println(o2.getIsim()); // Okunan nesne adı Ahmet olmalı...
}
}



İyi çalışmalar...

30 Haziran 2010 Çarşamba

Ford OTOSAN - jQuery Sunumu

Bünyesinde çalışmakta olduğum Ford OTOSAN firması Bilgi İşlem merkezinde geçtiğimiz günlerde jQuery JavaScript kütüphanesi hakkında genel bilgi ve tanıtım amacıyla bir sunum yaptım. Sunumda bahsettiğim uygulamaları video olarak hazırladım.


Genel hatlarıyla sunum içeriğinden bahsetmek gerekirse;

  • jQuery Nedir?

  • Kimler Kullanıyor?

  • Lisans ve Kullanım Koşulları

  • jQuery Kullanmak için 3 Temel Sebep

  • Kimlere Hitap Ediyor?

  • Kurulum Aşamaları

  • Temel Taşları

  • Basit Ajax İşlemleri

  • Asp.NET Web Formlar ve Web Servis Entegrasyonu

  • jQueryUI ile Etkileşimli Görsel Arayüzler

  • Eklenti Desteği


jQuery Sunum Dosyaları


Uygulama Videoları