الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

لنتعلم كيفية الربط بين openGL و WIN API

مغلق
بدأه Abdullah.Alshammeri في 14 ديسمبر 2005 · 7 رد · 4,846 مشاهدة · في OpenGL
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

لا ادعي الخبرة .. عشان ما تفهمونا غلط .... لكن هي محاولة لفهم عمل هذه المكتبة الرائعة GL

===

ربط opengl بالنافذة .. وبالنظام .... بوجه عام .. يتم عن عدة طرق ... اهمها عن طريق المكتبة glut او دوال النظام (API)

API طويلة نوعا ما ... لكن لا اتصور لعبة تعمل على الويندوز ولاتستخدم دوال API .

لذا سأفترض انك :

1- تجيد لغة السي .

2- تملك اساسا جيدا في win api .

الكود طويل نوعا ما ..

لكن ما اريدك ان تفهمه.. هو على أي اساس .. انشأنا مثل هذا الكود .

هل يجب ان يكون 21 سطر .. او 68 سطر ..

هل المسألة قص ولصق .

ام فهم . ام حفظ .

لا اريدك ان تسير مع الكود سطر بسطر ... كأننا في مادة القراءة في اولى ابتدائي .

ولا اريدك ان تحاول اتقان جانب الفلسفة .. والخروج عن صلب الموضوع الى احاديث ومناقشات نظرية . لاتغني ولاتسمن من جوع .

اريدك ان تنظر الى الكود نظرو واحدة وتعرف اجزائه ...

اولا نقسم عملنا الى عدة أقسام بهدف التنظيم .((دوال )).. اعيد واكرر ... تنظيم .

قسم يقوم باعداد النافذة ويربط نافذتنا بopengl ونسميه

CreateGLWindow()

وقسم يقوم بإعدادات opengl العامة ونسمي الدالة مثلا هممممم:

IntiGL()

ولكن اعدادات opengl كثيرة في البداية ستكون قليلة لكن بعد ان نتقدم سنتعلم كيف نعد الاضاءة والاكساء والماتيريال ونحو ذلك لذا سنقسم الدالة السابقة IntiGL() الى عدة اجزاء مثلا دالة ضوء دالة اكساء وهكذا ..

الان مبتدئين ..لذا لانحتاج الا الى اشياء بسيطة ,,

القسم الثالث او الدالة الثالثة هي التي ستعرض لنا مانرسمه وسنرسم بداخل هذه الدالة وسنسميها

render()

الدالة الرابعة هي التي ستقوم بتظبيط العرض او منفذ الرؤية على حسب حجم النافذة وسنسميها

ReShape(GLsizei width,GLsizei height)

قد تكون الدالة السابقة غير واضحة لكن لايهم ..

الدالة الخامسة هي الدالة التي ستمسح اثار لعبتنا .. وسنسميها

ShutDown()

هكذا سنقسم برنامجنا طبعا لايلزمك ان تتقيد بهذا التقسيم وطبعا لايجب ايضا التقيد باسماء الدوال لكن كل مانقوم به هو للتنظيم

---

اذا الشكل العام لبرنامجنا

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

استدعاء المكتبات

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

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

الاعلان عن المتغيرات العامة

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

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

الاعلان عن الدوال العامة

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

-----

دالة 1

-----

-----

دالة 2

-----

-----

دالة 3

-----

-----

دالة 4

-----

-----

دالة 5

-----

-----

دالة التعامل مع الراسائل المعروفة

-----

كما قلنا تقسيم البرنامج يساعد على استيعاب الدروس فقط .. وليس الزامي ..

وقد يسأل احد ويقول لماذا نعلن عن متغيرات عامة .؟

الجواب : حتى تستطيع اي دالة الوصول لذلك المتغير .. مثلا

متغير مقبض النافذة

تحتاجه عدة دوال : لذا لو اعلنا عن متغير داخل إحدى الدوال فلن نستطيع استخدامه لو احتجناه في دالة اخرى ..

* اخر دالة ستكون دالة التعامل مع الرسائل التي تعلمتها في WIN API

-----------

الدوران ...(LOOP)

هذا احد اهم المفاهيم التي ستبني عليه العابك ...

حسن الجودي سبقني ... :)

/index.php?showtopic=82793

لكن كنت كتبتها من فترة ... ولا مانع من عرضها .

استطيع اقول ان هناك نوعان من الدوال التي تستعملها في العابك :

دوال لاتحتاج الى ان تستدعيها اكثر من مرة واحدة .. مثلا اعداد opengl وربطه بالنافذة .. هنا لاتحتاج كل ثانية مثلا ان تستدعي الدالة التي تربط opengl بالنافذة !!!

يكفيك ان تستدعيها عن بداية البرنامج مرة واحدة وخلاص ..

لكن هناك دوال لابد ان تستدعيها عدة مرات وهي

1- دالة الرسم :: والتي اتفقنا على تسميتها بrender ..هذه الدالة تحتاجها طوال فترة البرنامج .. مثلا :

قمت برسم مربع .. وتريد تحريكه ؟؟ كيف ستحركه وانت لم تستدعيه الا مرة واحدة .

هذا يسمى اطار .. frame

فكل مرة نرجع ونستدعي دالة الرسم .. والتي ستحدث البيانات الموجودة على الشاشة لتضمن بقاء اللعبة في طور الحياة .. :)

الدالة الثانية والتي نحتاج الى جعلها تحت حلقة الدوران هي الدالة التي تستلم الرسائل .. يعني مثلا نقرة الكيبورد ..

فنحن طول وقت البرنامج ننتظر من المستخدم ضغط اي زر لنقوم بمعالجة الامر ..

اذا كيف نجعل اللعبة

تدور ... وتحدث نفسها ؟

الجواب باستخدام الحلقة التكرارية

while

مثال عام :

نعلن عن متغير من نوع boolean و قيمته اما صحيحة او خاطئة مثلا

bool EXIT =false;

اعلنا عن متغير وسميناه EXIT حتى يكون اسم واضح .. واعطيناه قيمة خطا

نقول :

مادام قيم EXIT = خطا ..

اذا قم بعمل التالي

1- استدعي دالة الرسم

rende()

2- عالج اوامر الادخال مثلا الكيبورد ..

اذا ضغط على الزر مثلا esc فاجعل قيمة المتغير EXIT = صح وبالتالي يختل شرط الحلقة الدوارانية فنخرج من اللعبة

اذا الامر واضح

نحدث اللعبة ثم نفحص ضغطات الكيبورد مثلا .. فاذا ضغط على زر معين اخرج من البرنامج واذا لم يضغط على ذلك الزر لاتخرج ..

الكود:

يجب ان تكون فاهم دوال API لمعرفة هذا الكود :

MSG        uMsg;



	while( uMsg.message != WM_QUIT )
	{
  if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
  {
  	TranslateMessage( &uMsg );
  	DispatchMessage( &uMsg );
  }
        else
  	render();
	}

	shutDown();

نقول

while( uMsg.message != WM_QUIT )

مادام الرسالة uMsg.message ليست دالة الخروج WM_QUIT اذا قم بالدخول في الحلقة الدورانية وهي :

if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
  {
  	TranslateMessage( &uMsg );
  	DispatchMessage( &uMsg );
  }

نقول اذا لاحظنا اي رسالة جديدة جاءتنا من الكيبورد او الماوس ونحو ذلك عندئذ قم بتحليل تلك الرسالة ..((ونحن نعرف من دوال API )) اننا نرسل الرسالة الى دالة الرسائل والتي عادة مانسميها WndProc

طيب اذا لم تصلنا اي ضغطة كيبورد ولا نقرة ماوس ماذا نفعل ؟

else
	render();
}

فاذا لم يصلنا اي حدث عندها قم باستدعاء دالة الرسم .. طبعا والتي نضع فيها بعض الرسم مثلا رسم مربع او مثلث .. الخ

وهكذا ..

ندور وندور حتى يصلنا رسالة الخروج WM_QUIT فاذا لم تأتي فان الحلقة ستدور وتحلل الرسائل ثم تستدعي دالة الرسم ...

طيب نفرض جاءنا امر الخروج WM_QUIT ... عندئذ سنخرج من الحلقة ونكمل ما بعد الحلقة الدوارانية ... ماذا يوجد بعدها ؟؟ لاحظ

shutDown();

اذا تدور اللعبة حتى ياتي امر الخروج عندئذ يتم الخروج من الحلقة لتجد الدالة shutDown(); التي تقوم بمسح اثار اللعبة ومن ثم الخروج من اللعبة نهائيا ..والعودة للويندوز ..

هذه صورة من كتاب red book توضح المقصودر بالفريم

14_12_05_02_42_18_1134556938clip_image_1.gif

هذه هي الفكرة اتمنى قبل ان تواصل ان تكون استوعبت الفكرة ..

انا كنت ارى مثل تلك الامور لكن لا اهتم لها .. فكان كل مايهمني شرح دالة ترسم مربع او مثلث .؟؟؟

هذا ليس مهم ..

المهم ان تعرف كيف تتم الامور في لعبتك ...

الخلاصة:

*اذا تعلمنا كيف نقسم لعبتنا

*تعلمنا ماهي الحلقة الدوارانية .

اذا لم تفهم السابق او تجاهلته .. فلا تحاول اكمال الطريق لانك وبكل اسف ستفشل !!

تم تعديل هذه المشاركة بواسطة الشمري في 14 ديسمبر 2005 في 14:35

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#2

Back Buffer

ماهو Back Buffer

هو سطح خفي نرسم عليه ثم بعد ان ننتهي من الرسم نقوم باحضاره الى الشاشة .

قد يسأل سائل ويقول مالفائدة من هذا السطح ..

الفائدة النعومة الكبيرة ... التي ستحصل عليها ..

مثلا في دوال الويندوز عندما نرسم شي ونحركه لاتظهر الحركة ناعمة انما يحدث وميض مزعج مشوه للرسم عند تحريكه .. السبب في ذلك اننا في الويندوز لايوجد الا سطح واحد هو الذي نرسم عليه .

وتستطيع ان تنشئ سطح خاص بك .. لترسم عليه ثم تقلبه .. لتظهر الحركة ناعمة ..

---

BUFFER في opengl انواع وهي :

1- Color buffer واسمه البرمجي GL_COLOR_BUFFER_BIT ( عبارة عن قيمة )

وهو السطح الرئيسي واللي سنستعمله في البداية ( للالوان )

2- Depth buffer واسمه البرمجي GL_DEPTH_BUFFER_BIT ( عبارة عن قيمة )

3- Accumulation buffer واسمه البرمجي GL_ACCUM_BUFFER_BIT ( عبارة عن قيمة )

4-Stencil buffer واسمه البرمجي GL_STENCIL_BUFFER_BIT ( عبارة عن قيمة )

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#3

الدرس الاول :

انشاء نافذة فارغة ...

يعني

ربط النافذة بـ OPENGL :

قبل هذا الدرس لابد ان تكون

1- مستواك جيد جدا جدا بالسي

2- مستواج جيد جدا بدوال API

3- تابعت الدروس الاعدادية السابقة .

وهي ...

والدرس السابق اللي فوق ..

اذا كنت فاهمها فانك ستفهم هذا الدرس ان شاء الله .

ولكن قبل ذلك احب ان اعرض صورة توضيحية تبين لك مسار اللعبة ودوالها .. وذلك اختصارا للكلام السابق ..

انظر للمرفقات ..

post-42837-1134560318_thumb.jpg

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#4

اولا استدعاء وربط المكتبات اللازمة وهي

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

 #include <windows.h>  
#include <gl\gl.h>   
#include <gl\glu.h>    
#include <gl\glaux.h>

الاعلان عن المتغيرات العامة

HDC  hDC=NULL;   
HGLRC  hRC=NULL;   
HWND  hWnd=NULL;  
HINSTANCE	hInstance;

كلها مرت عليك في WIN API باستثناء HGLRC .. هذا

يسمونه Rendering Context .. سياق التصيير  .. فهمتوا شيء .

يعني تطبيقات GL ترتبط بـ hglrc الذي بدوره يرتبط بـ DC الخاص بالويندوز ... و كما نعلم اذا اردنا الرسم الى نافذة ما ... يجب ان يكون هناك dc لها ....

الاعلان عن الدوال التي سنستعملها

LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  
void CreateGLWindow(char* title,int width,int height,int bits); 
void ReShape(GLsizei width,GLsizei height);
void InitGL();
void Render();
void ShutDown();

الدالة الاولى :

انشاء النافذة وربطها مع opengl .

void  CreateGLWindow(char* title, int width, int height, int bits )
{
	GLuint  PixelFormat;   
	WNDCLASS	wc;      
  RECT  WindowRect;     
	WindowRect.left=(long)0;    
	WindowRect.right=(long)width;   
	WindowRect.top=(long)0;     
	WindowRect.bottom=(long)height;  


	hInstance  	= GetModuleHandle(NULL);     
	wc.style  	= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  
	wc.lpfnWndProc  = (WNDPROC) WndProc;       
	wc.cbClsExtra  = 0;          
	wc.cbWndExtra  = 0;          
	wc.hInstance  = hInstance;       
	wc.hIcon  	= LoadIcon(NULL, IDI_WINLOGO);   
	wc.hCursor  	= LoadCursor(NULL, IDC_ARROW);   
	wc.hbrBackground	= NULL;         
	wc.lpszMenuName  = NULL;          
	wc.lpszClassName	= "OpenGL";         

	RegisterClass(&wc);       

  

	AdjustWindowRectEx(&WindowRect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);  // Adjust Window To True Requested Size

  hWnd=CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,        
        "OpenGL",        
        title,         
        WS_OVERLAPPEDWINDOW |       
        WS_CLIPSIBLINGS |      
        WS_CLIPCHILDREN,      
        0, 0,         
        WindowRect.right-WindowRect.left,   
        WindowRect.bottom-WindowRect.top,  
        NULL,         
        NULL,         
        hInstance,        
        NULL); 
  hDC=GetDC(hWnd);

الكود السابق .. كود عادي ... لبناء نافذة .

الصق هذا

	PIXELFORMATDESCRIPTOR pfd;
	memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));

    pfd.nSize      = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion   = 1;
 pfd.dwFlags    = PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL | 
      PFD_DOUBLEBUFFER;

    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 16;
    pfd.cDepthBits = 16;


	PixelFormat=ChoosePixelFormat(hDC,&pfd); 
	SetPixelFormat(hDC,PixelFormat,&pfd);

	hRC=wglCreateContext(hDC);  
	wglMakeCurrent(hDC,hRC);    
	ShowWindow(hWnd,SW_SHOW);   
	SetForegroundWindow(hWnd);      
	SetFocus(hWnd);
	ShowCursor(FALSE);



}

اول امر مهم ... هو

	static	PIXELFORMATDESCRIPTOR pfd=

هذا التركيب .. من الويندوز نفسه ..يعني ليس خاصا بـ GL .

بماذا يفيدنا .

نقوم بتعبئة بعض متغيرات التركيب .. ببعض القيم ..

مثلا

هل نريد buffer ( سطح خلفي) .. وبالتالي نزيد نعومة الحركة ..والرسم .

هل نريد نظام الوان RGB او RGBA .

هل نريد الدقة 16 بت او 32 بت ...

وغيرها الكثير .

لكن اغلب القيم لانحتاج تغييرها .

لننظر ماذا فعلنا .

   memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));

    pfd.nSize      = sizeof(PIXELFORMATDESCRIPTOR);

خطويتين دائما ماتتكرر مع تراكيب الويندوز . . . واعتقد واضحة .

pfd.nVersion = 1;

رقم نسخة ما :D .. لايهم .. دائما واحد .

    pfd.dwFlags    = PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

مهم

هنا نحدد الخصائص العامة .. حتى نعرف كيف سيكون تطبيقنا .

اولا قلنا PFD_DRAW_TO_WINDOW يعني نريد نرسم الى نافذة

PFD_SUPPORT_OPENGL .. نخبر النظام اننا نريد استخدام OPENGL

PFD_DOUBLEBUFFER .. نريد سطحين ( BACK BUFFER)

    pfd.iPixelType = PFD_TYPE_RGBA;

هنا اخترنا نظام الالوان RGBA - قناة ALPHA .

وتستطيع اختيار Index color عن طريق تمرير الثابت PFD_TYPE_COLORINDEX

    pfd.cColorBits = bits;
    pfd.cDepthBits = 16;

الاولى دقة الالوان .. نحن سندخلها في وقت لاحق ..عن طريق بارمتر الدالة .. bits

8 بت .. 16 .. 24 .. 32 ..

اما الثانية .. لاتهمنا الان :) ,, >>> تصريف

الان اعددنا الملامح التي نريد ... لكن الى الان لم يحدث شيء .. يجب ان نفعل خياراتنا .

	PixelFormat=ChoosePixelFormat(hDC,&pfd); 
	SetPixelFormat(hDC,PixelFormat,&pfd);

اخترنا الاعدادات التي نريد .. ثم فعلناها .. على hDC ..

الان اخر خطوة ..

	hRC=wglCreateContext(hDC);  
	wglMakeCurrent(hDC,hRC);

انشأنا Rendering Context من dc ... الخاص بنافذتنا .. وربطناهما مع بعض ... . لا يهم كثيرا التفاصيل .. المهم . هذه طريقة الربط . (h)

خلاص الان ربطت opengl بالنافذة .. بقي ان نظهرها .. ونخفي المؤشر ..حتى لايشوه التطبيق , ,,

	ShowWindow(hWnd,SW_SHOW);   
	SetForegroundWindow(hWnd);      
	SetFocus(hWnd);
	ShowCursor(FALSE);

الان ربطت النافذة ... بـ Opengl

لاحظ انها تمر بثلاث مراحل .

انشاء النافذة بالطريقة العادية .

انشاء الاعدادات التي نريدها ... مثل نظام الالوان ....

ربط النافذة بـ GL عن طريق .. wglMakeCurrent

لاحظ ان دوال الويندوز .. لم اشرحها ... افترض انك فاهمها ,,

الخطوة القادمة .. هي اعداد opengl و كتابة كود دالة اعادة التحجيم Reshape ....

قسمت الموضوع الى عدة اجزاء .. حتى لايكون الموضوع ممل بالحيل ...( بالرغم من انه ممل ) ,

تم تعديل هذه المشاركة بواسطة الشمري في 14 ديسمبر 2005 في 14:54

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#5

الدالة الثانية اعادة تحجيم وتغيير منفذة العرض ..

void ReShape(GLsizei width,GLsizei height) 
{
  if (height==0)          
	{
  height=1;          
	}

	glViewport(0,0,width,height);       

	glMatrixMode(GL_PROJECTION);      
	glLoadIdentity();         

  gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);      
	glLoadIdentity();        
}

لايهم فهمها الان .. سأشرحها لاحقا بحول الله وقوته .. . اقصد سأحاول شرحها لاني مش فاهمها 100% .

لكن لاحظ اننا وضعنا بارمتريتن الاول عرض النافذة والاخر طولها .. اذا كل ما سبق مهمته .. وضع الجسم في النافذة بالمكان السليم ..

الدالة الثالثة اعدادات opengl ..

الان لايوجد الكثير من الاعدادات ..

void InitGL()
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glEnable(GL_DEPTH_TEST);
}

الدالة glClearColor تغير لون الخلفية .. واخترن اللون الاسود حيث تطلب اربع بارمترات تمثل قنوان الالون الاربع RGBA .. A هو الالفا .. اما R فهو الاحمر و G الاخضر و B الازرق ..

اما glEnable .. فهي احد دوال GL المشهورة ستمر عليك كثيرا .

الان مررنا له بارمتر .. GL_DEPTH_TEST .. ويعني اننا نريد استخدام البعد Z ... عمق الشاشة ..يعني ثريدي.

الان الدالة التي ستمسح اثار اللعبة .

void ShutDown( void )
{

	if(  hRC != NULL )
	{
  wglMakeCurrent( NULL, NULL );
  wglDeleteContext(  hRC );
   hRC = NULL;
	}

	if( hDC != NULL )
	{
  ReleaseDC( hWnd, hDC );
  hDC = NULL;
	}
}

واضحة زي الشمس .. مسحنا HGLRC و HDC ..

ممكن تمسح ايضا بعض القيم ايضا من الذاكرة ... لكن لاتهم كثيرا .. راجع دروس NEHE للاستفادة اكثر .

الان الدالة التي سنرسم فيها .. التي سيتم تحديثها باستمرار ...

void Render()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glLoadIdentity();
}

الدالة glClear : اقدر اقول انها تمسح البتات (لاسطح معينة .) وهي الان GL_COLOR_BUFFER_ ..

و GL_DEPTH_BUFFER_BIT السطح الخلفي اللي نرسم عليه .

اذا كنت ترسم على سطح واحد فقط Single Buffer ,, فلا تضيف GL_DEPTH_BUFFER_BIT .

قد تستخدم اسطح اخرى .

GL_ACCUM_BUFFER_BIT

GL_STENCIL_BUFFER_BIT

,,,,

اما الدالة

glLoadIdentity();

فتقوم بتصفير المصفوفة ..

يعني نرجع لنقطة الاصل وهي منتصف الشاشة . . .

ايضا نوع المصفوفة التي نتعامل معها الان .. هي GL_MODELVIEW ..

سنناقش هذا الموضوع لاحقا ... انا عن نفسي ... توجد عندي اشكالات :(

الان الدالة الرئيسية :

int WINAPI WinMain(	HINSTANCE hInstance_,HINSTANCE hPrevInstance,
LPSTR	lpCmdLine,int nCmdShow)
{
	MSG  msg;      
	BOOL	done=FALSE;     

	CreateGLWindow("OpenGL Framework",640,480,16  );
	ReShape(640,800);
	InitGL();

	while(!done) 
	{
   PeekMessage(&msg,NULL,0,0,PM_REMOVE);  
   
  	if (msg.message==WM_QUIT)    
  	{
    done=TRUE;   
  	}
  	else
  	{

  	Render();     
  	SwapBuffers(hDC);	


  	TranslateMessage(&msg);    
  	DispatchMessage(&msg);    
  	}

      
    

  
	}

  ShutDown();         
	return (msg.wParam);

}

اولا .. استدعينا الدالة التي تنشئ النافذة وتربطها مع GL

ثم استدعينا الدالة التي تظبط منطقة العرض في opengl .

ثم استدعينا الدالة التي تعد opengl ..

وهي كلها امور لانحتاج لاستدعائها اكثر من مرة واحدة .

اما دالة الرسم .

Render .. فوضعناها في LOOP حتى يتم تحديث الرسم ... ولن نخرج من loop الا اذا صار المتغير

done = treu

وذلك عندما تأتينا رسالة الخروج Quit ,,

اذا خرجنا من loop .. ننتقل للدالة ShutDown التي تمسح اثار التطبيق .. ثم يغلق الرنامج . والسلام عليكم .

بقي دالة تفسير الرسائل المألوفة ..

LRESULT CALLBACK WndProc( HWND  hWnd, UINT  msg,WPARAM wParam, LPARAM lParam )
{

    switch( msg )
	{

        case WM_KEYDOWN:
  {
  	if( wParam ==VK_ESCAPE )
    	PostQuitMessage(0);    
    
  }
        break;

  	case WM_SIZE:
  {
    	ReShape(LOWORD(lParam),HIWORD(lParam));
  }
  break;

  case WM_CLOSE:
        case WM_DESTROY:
  {
            PostQuitMessage(0);
  }
        break;
  
  default:
  {
  	return DefWindowProc( hWnd, msg, wParam, lParam );
  }
  break;
	}

	return 0;
}

لا يوجد شيء جديد ..

الا شيء واحد ..

case WM_SIZE:
  {
	ReShape(LOWORD(lParam),HIWORD(lParam));
  }
  break;

اذا تغير حجم النافذة ..

نحصل على الحجم الجديد عن طريق بيانات الرسالة ... LOWORD(lParam),HIWORD(lParam)

اعتقد انك تعرف ماذا تعني .. لانها امور تختص بـ WIN API .

حصلنا على طول وعرض النافذة ... مررنا الطول والعرض كبارمترات للدالة التي انشأناها ReShape

وبالتالي تؤدي الدالة ReShape العمل المطلوب منها ..

الهدف الرئيسي من هذا الموضوع .. فهم كيفية الربط بين GL و WINDOWS .. اذا فهمت هذه النقطة فان هذا الموضوع حقق مبتغاه ...

بقي الدالة Reshape سنحاول اللعب بها حتى نحصل على فهم اكثر .ان شاء الله . . .

تنبيه !!!!

الكود غير عملي كثيرا .. فنحن لانتأكد من سير كل شيء على ما يرام .. لم نكتب كل الاكواد المطلوبة ..

وستجد ان الكود المكتوب اقصر من اكواد موقع NEHE .. حيث التزمنا فقط بالامور المهمة .

الكود بالمرفقات ,,

gl_and_win32.zip

تم تعديل هذه المشاركة بواسطة الشمري في 15 ديسمبر 2005 في 22:06

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#6

نسيت شي ..

  Render();     
  SwapBuffers(hDC);

الدالة Swap من اسمها ... تحضر الرسم اللي رسمناه في الباك بفر ... الى المقدمة .. وبلتالي يظهر الرسم .

دائما نستخدم SwapBuffers بعد ان نرسم ..

لاحظ ايضا اننا لم نستخدم الدالة glFlush ... هذه الدالة لانستخدمها الا اذا كنا نعمل على سطح واحد .Single Buffer .

اما اذا استخدمنا سطحين .. فنستخدم الدالة Swap .. التي بدورها تستخدم glFlush ...

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#7

روح يشيخ ربنا يخليك .. و يعطيك حتى يرضيك ..

و يعينك ويثبتك على ما انت عليه من عمل الخير ...

و ان شاء الله الاسئلة في الطريق .. بس يكون تتحملني :rolleyes:

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#8

السلام عليكم و رحمة الله وبركاته ..

كيف حالك أخي الكريم ..

جزاك الله خيرا ..

اقتباس
((

BUFFER في opengl انواع وهي :

1- Color buffer واسمه البرمجي GL_COLOR_BUFFER_BIT ( عبارة عن قيمة )

وهو السطح الرئيسي واللي سنستعمله في البداية ( للالوان )

2- Depth buffer واسمه البرمجي GL_DEPTH_BUFFER_BIT ( عبارة عن قيمة )

3- Accumulation buffer واسمه البرمجي GL_ACCUM_BUFFER_BIT ( عبارة عن قيمة )

4-Stencil buffer واسمه البرمجي GL_STENCIL_BUFFER_BIT ( عبارة عن قيمة )    )))

اخي ممكن توضيح شوي على هذه الانواع واش الفرق وما هي فائدة كل واحدة منها ..

يعني احنا نستخدمه هنا

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glLoadIdentity();

ممكن توضيح على هل دالتين ؟؟

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

ما فائدة الجمل التي في الأعلى ..

يعني أنا لم استخدمها في أي برنامج .. والبرامج شغالة مية مية !!

WindowRect.left=(long)0; 
WindowRect.right=(long)width; 
WindowRect.top=(long)0; 
WindowRect.bottom=(long)height;

هذه الجمل .. ممكن أن نستغني عنها بأستخدام الدالة

GetClientRect

و ممكن توضيح عمل الدالة

AdjustWindowRectEx

…

بصراحة أنا لسا ما كملت الدرس هذا

ببساطة ..لأن الشرط لا ينطبق علي !!!!!!!

اقتباس
مستواك جيد جدا بدوال API

(هذا بعد تعديل الخطأ المطبعي ;) )

الكود تعقد و الدوال كثرت ..

و دماغي بدا يلف :blink:

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

هذا الموضوع مغلق.

مواضيع مشابهة