BAYAN.M.AZEEZ

(تنبيه : عنوان مخالف ) استفسار

6 ردود في هذا الموضوع

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

كالعاده اريد الاستفسار

في برنامجي عندما تظهر شاشه التنفيذ يكون مرسوم عليها بعض الرسومات ، اريد ان اضغط على مكان معين من الشاشه بحيث

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

انا عملت 2 فنكشن كل واحد برسم رسومات معينه

وعملت فنكشن الماوس وداخله جملة if

بحيث اني اذا ضغطت على منطقه معينه يسندعيلي الفنكشن التاني واللي اكيد ببدأه بجملة مسح الشاشهglClear.........

وبس طبقته ما عمل إشي؟؟

البرنامج مرفق

ارجو المساعده

arab.cpp

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

وينكوا يا جماعه

اريد مساعده عاجله من فضلكم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مرحبا أحي, طلبك رائع جدا, في نظري إضنك توصلت إلى الفكرة الأساسية في برمجة الألعاب و هي برمجة "محرر الرسوم" هذا المحرر مثل أي محرر رسومات أخر ك 3ds max مثلا و المعروف أن مثل هذه البرامج باهضة الثمن, لذى لا حل سوى برمجة تطبيق خاص بنا , حقيقة أنا الأن أخطط لبدأ هذا المشروع و الحسابات ستنتهي قريبا إن شاء الله و سأربطه برخصة "وقف الإسلامية" إن شاء الله.

على فكرة كان هذا كله لأريك أن موضوعك في غاية الأهمية تبدأعلى بركة الله

إن برنامجك ليس سيأ البتة و لكن ينقصه كثيرا من الجوانب

إن الإعتماد على مواصفات الفأرة (موقع مؤشر الفأرة و حالتاها) في رسم و تحديد أشكال في موضع ما من عالم الأوبن جي أل تعد فكرة سيئة للغاية حيث أن النظام سيرجع المواصفات حتى و لو خرج مؤشر الفأرة من مجال نافذة الأوبن جي أل, لذا و لهذا السبب و جد طريقة أخرى لتحديد المواضع و المجسمات داخل عالم الأوبن جي أل.

الإختيار و النقر selection وpicking هذا النوعان سميهما محوران في علم الأبن جي أل ,

هذان الأخيران يحددان موضع الفأرة بالنسبة لعين النظر القائمة و موضعها في شاشة نافذة الأوبن جي أل و بهذه الطريقة نحصل على شعاع إن صح الأمر

كما قلنا أكرر ,الشعاع يبدأ من الخارج تماما من عينيك و يتجه نحو موضع مؤشؤر الفأرة الموجود على نافذة الأبن جي أل فقط ثم يدخل عالم الأبن جي أل و يمتد إلى المالانهاية, فأي جسم و أي شكل من الأجسام و أي شيء مر عليه الشعاع يضعه في مصفوفة , الشعاع حينما يخترق جسم ما لا يؤثر عليه و لكن يتولد عن إصطدام الشعاع بالجسم معلومات عن هذا الجسم و هذه المعلومات يضعها الشعاع في مصفوفته و يكمل الشعاع مساره ليخترق أجسام أخرى إن مر عليها.و في الأخير سيرجع هذا الشعاع عدد الأجسام الذي إصطدم بها.

حسنا ما وصفته الإصطدام و الإختراق يدعى بالإنجليزية hits recorder .

نعود إلى طرح بعض الأسإلة :

س- كيف نتعرف على الجسم من بين الأجسام الأخرى حينما يقع عليها الشعاع؟

ج-في البداية ليكن في علمك أن هذ العملية ليست عبارة عن سطر برمجي واحد بل هي عبارة عن سطور , ففي السير بين هذه السطور ستلاحظ أنك حينما تريد رسم شكل ما تحدد له إسم, فعندما يحدث الإصطدام يتعرف الشعاع على هذا الجسم عن طريق الإسم المحدد له مسبقا.

س-كيف أحصل على هذا الإسم لأن الشعاع سيرجع الإسم و بيانات عن هذا الإسم ؟

ج-للوصول إلى الإسم يجب التمرين على أمثلة جاهزة مسبقا , لأن الحديث عنها يستوجب الحديث عن أشياء أخرى.

س-لقد قلت أن الشعاع سيمر و سيتولد إصطدام على أي جسم يجده أمامه, كيف يتم الترتيب و كيف نفرق بين هذ المعلومات قد لا تحتوي مجسم واحد بل أكثر؟

ج- حسنا يتم وضع هذه المعلومات في مصفوفة واحدة (على فكرة المصفوفة يجب أن تكون كافية لعدد الإصطدامات و إلا ستحدث الكارثة "إنفجار داخل عالم الأوبن جي أل") و الترتيب مهم فالإصطدام الأول يبقى الأول و الثاني يبقى الثانى و هكذا دواليك إلى أخر إصطدام, التفريق بين البيانات يبقى عليك التمرين على أمثلة جاهزة مسبقا.

حسنا إعلم أن كل ما تحدثت عليه تفعله المكتبة glu و ليس gl أي أنها ليست مرتبطة بالعتاد و بإمكانك الإستغناء عنها إن وجدت وسيلة أخرى.

على فكرة لم يكن هذا نقدا بل كان هذا حق على توجيهك الطريق الصحيح و الكل يخطأ و يبقى "الله جل و على" الكامل بين خلقه أجمعين.

عموما إليك هذا الرابط قد تجد شرحا موجزا لما قلته, و إن كان عليه بعض الأخطاء النحوية و الفكرية إلا أنها ليست خطرة, فهو موضوع يتحدث عن هذا الجانب من كل الجوانب و لن تجد مثله في النت .

http://www.startimes2.com/f.aspx?t=19594413

http://www.startimes2.com/f.aspx?t=19587641

أه نسيت شيأ:

الفرق بين الselection و picking وبين (التغدية المرجعية feedback ) هو أن:

selection و picking لا تأثر على رسم الأشكال كأن تضيف أو تغير شكل في موضع تحدده بنفسك في عالم الأوبن جي أل تماما كمثالك.عند مرورك إلى نمط الإختيار selection سيكون بإمكانك التعديل على مجسمات لتعرض على الشاشة أي بإمكانك التعديل على ذاكرة الإيطار framebuffer .

أما التغذية المرجعية فإنك حينما تمر إلى نمط التغذية المرجعية سيتجمد عالم الأوبن جي أل كليا ريثما تخرج إلى نمط التصيير render , هذا لا يصب في مصلحتك مطلقا, ولن تتمكن من التعديل على ذاكرة الإيطار و أنت في نمط feedback.

خاص ببرنامجك: الدالة main التي في مثالك يجب أن ترجع متغير , لذى عليك جعلها كذلك

من void main إلى int main.

أتمنى لك التوفيق

تم تعديل بواسطه 3ds max2010
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم،

محور المشكلة هو أن ضغطة الماوس تحصل في الشاشة ثنائية الأبعاد، لذلك فليس هنالك Z، فقط X و Y بالنسبة لنافذة العرض، بينما المشهد يعمل في فضاء ثلاثي الأبعاد بأسقاط منظوري (غير منتظم) وبإحداثياته الخاصة، كيف سيتم تحويل هذا إلى ذلك؟

لقد وضعت رداً يفصل إلى درجة ما الطريقة التقليدية لحل هذه المشكلة (ray picking) ولكن استخدمت كمثال للكود Direct3D ويمكن تحويله بسهولة إلى OpenGL، قد يبدو الأمر صعباً للوهلة الأولى، ولكنه من نوع الأشياء التي لا يجب عملها أكثر من مرة واحدة فقط، إجراء واحد يأخذ إحداثيات ضغطة الماوس ويعيد شعاعاً يبدأ من نقطة ضغط الماوس ويتجه نحو الشاشة عمودي عليها وينتهي الموضوع.

الرد رقم 4 هنا.

أتمنى أن يكون ذلك ذو فائدة

:)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

شكرا لكم

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

ربما احتاج الى امثله اكتر.

لكن اريد ان أسأل عن glunproject لقد قرأت عنه انه يقوم بالتحويل من window map الى project

وهو يأخذ 6 ارقمنت وهم احداثيات x,y,z والتلاته الاخرى لم استطع التعامل معهما لذلك لم اجربه!!!

هل هذا الفانكشن يقوم بما تم شرحه في المشاركات ؟؟؟؟

وان كان كذلك ارجو توضيحه لي

وشكرا لكم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مرحبا,

لو قرأت الموضوعان الذان وضعتهما في الرابطان لفهمت الأمر, لكن لن أخيب الضن و بهذا أفترض أنك لا تعرف الإسقاط جيدا

لذى سأوضح, ما تحدث عنه سابقا يخص العالم الثلاثي الأبعاد بشكل مائة بالمائة أما gluUnProject فهي أيظا تعمل في المعالم الثلاثية الأبعاد و لكن مفعولها ضعيف جدا.

إن دالة gluUnProject تستعمل غالبا في التطبيقلات الثنائية الأبعاد, فدالة gluUnProject ترغمك على تثبيت قيمة z


gluUnProject ((GLdouble) x, (GLdouble) (viewport[3] - (GLint) y - 1), 0.0,model_view_matrix, projection_matrix, view_port_matrix, &World_coords_x, &World_coords_y, &World_coords_z);

l

هذه الدالة لديها ستة برمترات مدخلة و ثلاثة بارمترات مخرجة, وترجع هذه الدالة القيمة صفر في حالة الإخفاق و القمية واحد في حالة نجاح العملية.

البارمتر الأول و الثاني يدلان على موقع الفأرة على شاشة لكن فقط في مجال نافذة الأوبن جي أل, أما البراميتر الثالث فهو المشكلة لذا تابعني بحذر

تخيل أنك تستطيع أن تدخل يدك في الشاشة ( طبعا هذا مستحيل و لكن تخيل) و أمسك نافذة الأوبن جي أل بيدك و أخرجها للخارج بمسافة 20 سم

نفرض أن 20سم تساوي 400 بكسل , إذا ما هي إحداثيات الفأرة الأن في المحور z, إحداثيات الفأرة هي 400+.

هل فهمت الأن.

غالبا ما تأخذ القيمة z بالقيمة صفر.

البارمتر الرابع هو مصفوفة رؤية النموذج .نتحصل عليه عن طريق الدالة glGetDoublev .

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

البراميتر السادس هو مصفوفة منفذ الرؤية. نتحصل عليه عن طريق الدالة glGetIntegerv .

البرامترات الباقية هي مؤشرات لموضع مؤشر الفأرة في عالم الأوبن جي أل.

على فكرة هذه الدالة تعمل بكفائة جيدة و لكن ستفشل لو غيرت مجال العمق depth range عن طريق الدالة glDepthRange, فلحل هذه المشكلة نستعمل الإصدارة glu 1.3 فما فوق , فهي تزودنا بدالة glUnProject4.


GLint gluUnProject4 ( GLdouble winX , GLdouble winY , GLdouble winZ , GLdouble clipW , const GLdouble *model , const GLdouble *proj , const GLint *view , GLdouble near , GLdouble far , GLdouble* objX , GLdouble* objY , GLdouble* objZ , GLdouble* objW );

l البراميتر من1حتى 4 هما إحداثيات مؤشر الفأرة في النافذة , البارميترات من 5 إلى 7 هما نفس الموجودين في الدالة الأولى , أما البرامتران 8 و9 فهما يمثلان قيمة القرب و قيمة البعد المحددان بالدالة glDepthRange.و نتحصل عليهما عن طريق الدالة glGetDoublev . و ال 4 برمترات الباقية هي لموضع المؤشر في عالم الأوبن جي أل.

و دالة glProject هي عكس دالة glUnProject .


int gluProject(GLdouble objx, GLdouble objy, GLdouble objz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *winx, GLdouble *winy, GLdouble *winz);

نعطيها إحداثيات موضع ما في عالم الأوبن جي أل و تعطينا إحداثياته في معلم النافذة , تخيل أنها سترجع قيمة لمحور z الخاص بالنافذة و حقا ذلك سيحدث.

عموما أنا إعتمدت على مؤشر الفأرة كمثال في الشرح , إذ أنه لا يقتصر على مؤشر الفأرة فقط بل ستتعدد الوظائف في ذلك.

l


#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}

/* Change these values for a different transformation */
void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (45.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void mouse(int button, int state, int x, int y)
{
GLint viewport[4];
GLdouble mvmatrix[16], projmatrix[16];
GLint realy; /* OpenGL y coordinate position */
GLdouble wx, wy, wz; /* returned world x, y, z coords */

switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
glGetIntegerv (GL_VIEWPORT, viewport);
glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
/* note viewport[3] is height of window in pixels */
realy = viewport[3] - (GLint) y - 1;
printf ("Coordinates at cursor are (%4d, %4d)\n", x, realy);
gluUnProject ((GLdouble) x, (GLdouble) realy, 0.0,
mvmatrix, projmatrix, viewport, &wx, &wy, &wz);
printf ("World coords at z=0.0 are (%f, %f, %f)\n",
wx, wy, wz);
gluUnProject ((GLdouble) x, (GLdouble) realy, 1.0,
mvmatrix, projmatrix, viewport, &wx, &wy, &wz);
printf ("World coords at z=1.0 are (%f, %f, %f)\n",
wx, wy, wz);
}
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
exit(0);
break;
default:
break;
}
}

/* ARGSUSED1 */
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}

/*
* Open window, register input callback functions
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc (keyboard);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

l هذا مثال من redbook .

تم تعديل بواسطه 3ds max2010
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .