עבור לתוכן

עזרה בOpenGL - ציור בדו-מימד

Featured Replies

פורסם

היי,

אני מחפש דרך לצייר בדו מימד בחלון שלי (לצייר מסגרת לחלון בעיקרון) ואחר כך לרנדר כמה גופי תלת מימדיים בהטלה פרספקטיבית, חיפשתי בopengl faq ושמה הוצעה הדרך הבאה :

רינדור של פריים אחד:

בצע הטלה אורתוגרפית.

צייר בדו מימד.

בצע הטלה פרספקטיבית.

צייר תלת מימד.

על פניו זה עובד טוב אבל זה נראה לי מאוד "בזבזני" - יש למישהו דרך אחרת לעשות את זה ?

[left]

void R(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D (0, 150, 0, 150);
glMatrixMode (GL_MODELVIEW); glLoadIdentity ();
glTranslatef (0.375, 0.375, 0.);
glColor3f(1.0f, 1.0f, 1.0f);
// glDisable(GL_DEPTH_TEST);

glRectf(0,0,150,150);
//glEnable(GL_DEPTH_TEST);
glColor3f(0.0f, 0.0f, 0.0f);
glRecti(2,2,148,148);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20.0f, 1.33, 1.0f, 20.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5,0,0,0,0,1,0);
glPushMatrix();
glRotatef(angle,1,1,1);
// glScalef(200,200,200);
glColor3f(1.0f, 0.0f, 1.0f);
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++)
for(int k=- 1;k<=1;k++){
glPushMatrix();
glTranslatef((float)i*cubeSize, (float)j*cubeSize, (float)k*cubeSize);
if (piece1[i+1][j+1][k+1]!=0)
glutWireCube(cubeSize);
glPopMatrix();
}
glPopMatrix();
angle+=3;
if (angle==360)
angle==0;
glutSwapBuffers();
}[/left]

פורסם

מסגרת אתה יכול פשוט לעשות עם פרמטיבים, אתה רוצה לרנדר 3D או לעשות raycasting? לא הבנתי בדיוק.

פורסם
  • מחבר

אני רוצה מסגרת לבנה פשוטה (תכלס מלבן) מסביב לחלון (שיצרתי עם glutCreateSubWindow) שבתוכו אני מצייר גופים תלת מימדיים(המסגרת כמובן לא זזה).

פורסם

יש לך 2 דרכים לעשות את זה, 1 בצורה פשוטה עם פרמטיבים רק צריך לדאוג שהם כל הזמן יופיעו בscreenspace שלך.

2 משהו קצת יותר מורכב:


glMatrixMode(GL_PROJECTION); glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
[b]glDisable(GL_DEPTH_TEST);
[/b]

חשוב לבטל את בדיקות העומק, אחרת זה ישבש לך את כל התמונה.

ההגדרת הקורדינאטות באורט'ו אמורה להיות ככה:


void glOrtho
( GLdouble left
, GLdouble right
, GLdouble bottom
, GLdouble top
, GLdouble zNear
, GLdouble zFar
);

ציור של קוביה או כל דבר אחר בדו מיימד משהו כזה(קורדינאטות עם כוון השעון).


glBegin(GL_QUADS);

glColor3ub(X, Y, Z);


glVertex3f(-X, Y, 0);
glVertex3f(X, Y, 0);
glVertex3f(X, -Y, 0);
glVertex3f(-X, -Y, 0);
glEnd();

אני מניח שאתה מבין למה הקורדינאטות אמורות להיות ככה, בגלל ההבדל בין הקורדיאנטות הפיקסליות של המסך, למערכת הקורדינאטות של הscreenspace שלך.

-1,1======1,1

| |

| |

| |

-1,-1=====1,-1

ואחרי זה תטען טקסטורה על זה שאני דיי בטוח שאתה תסתדר, כן דיי גס אבל אין לי כוח עכשיו להתחיל לבדוק את זה עד הסוף, אם עדיין לא תסתדר ותבין את הכיוון אני אשתדל לכתוב את כל העניין מחר ולהביא קוד מלא.

בכל מקרה התוצר הסופי אמור להרות משהו כזה:


GLuint texture_number;
BITMAP *my_bitmap;



glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture_number);


glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

glBegin(GL_QUADS);

glColor4ub(255, 255, 255, 255);


glTexCoord2f(0, 0); glVertex3f(-X, Y, 0);
glTexCoord2f(1, 0); glVertex3f(X, Y, 0);
glTexCoord2f(1, 1); glVertex3f(X, -Y, 0);
glTexCoord2f(0, 1); glVertex3f(-X, -Y, 0);
glEnd();



פורסם
  • מחבר

אוקיי אני מבין מה שאתה אומר פה, בוא נגיד שעכשיו אחרי שציירתי את זה אני רוצה לצייר גופים תלת מימדיים בפרספקטיבה, אני אצטרך מן הסתם לחשב מחדש את המטריצה של הפרספקטיבה ואז לצייר את הגוף התלת מימדי שלי ? (זה מה שכתבתי בקוד למעלה).

אני מעלה תמונה למה שאני מתכוון :

(חלון שנוצר עם glutCreateSubWindow בתוך mainWindow)

*שוב אני אומר - זה עובד לי כמו שצריך אבל נראה לי מאוד בזבני *

**עריכה: עבודה עם טקסטורות היא לא הרבה יותר "כבדה" מאשר עבודה של ציור קווים מלבנים וכו ?

[attachment deleted by admin]

פורסם

כן בוודאי, אתה לא יכול לרנדר 2D ואז 3D עם אותה פרספקטיבה(אין לך Z בכלל ב2D!) אלא אם אתה יוצר מסגרת "מזוייפת" בעזרת פרמטיבים בפרספקיטבה התלת מיימדית, יש דרך לעשות overlay של טקסטורות בחלון אבל אני לא יודע אם זה תקף לsubwindow, ואני אישית לא השתמשתי בזה מעולם.

אתה עובד עם subwindow זה יכול להיות בעייתי אני אחפש פתרון יותר יעיל אולי יש משהו למרות שאני לא בטוח שאני אמצא\אחשוב על משעו.

פורסם
  • מחבר

סבבה תודה, ולאיזה בעיות אני יכול לצפות בעבודה עם subwindows ? בינתיים זה עובד די טוב.

פורסם

אני רחוק מלהיות מומחה בOpenGL, אבל יש גם את glDrawPixels.

http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/drawpixels.html

חסרון אחד שאני יכול לחשוב עליו זה שאם אתה רוצה לצייר משהו קבוע, אז חבל על ה-bandwidth. אבל אם בכל מקרה כל פעם אתה מצייר משהו שונה, אז אולי עדיף drawpixels?

פורסם

הוא מצייר מסגרת, לעשות את זה עם פיקסלים זה סיוט מוחלט או טקסטורה בארוט'ו או טקסטורה על פרמטיבים ב3D.

פורסם
  • מחבר

חשבתי על הפוקנציה הזאת אבל של הdrawPixels אבל לא הבנתי איך בדיוק היא עובדת, ולמה חבל על הbandwidth.

למה זה יהיה סיוט ? אם היא מציירת פיקסלים למסך (או לCOLOR_BUFFER_BIT) זה יכול דווקא לעזור לי.

בכלל זה מוזר (רק לי?) שבAPI של OpenGL אין אפשרות לצייר פיקסל ל.COLOR_BUFFER_BIT

פורסם

הוא מצייר מסגרת, לעשות את זה עם פיקסלים זה סיוט מוחלט או טקסטורה בארוט'ו או טקסטורה על פרמטיבים ב3D.

גם אני לא מבין למה זה סיוט. 4 קריאות לפונקציה ויש לך מסגרת.

פורסם

כי אתה מבזבז עוד כתיבה לFramebuffer, כלומר עוד בזבוז של רוחב פס. סיוט לעבודה איתה כיוון שהיא עושה בעיות במיוחד כאשר עובדים עם offscreen frame buffer או עם render targets.

ואיך אתה רוצה לצייר פיקסל לcolor buffer הוא מכיל מידע על הצבע של הפיקסלים, אתה לא יכול להגדיר לו שמה נקודה.

אתה צריך "ליצור" את הפיקסל כדי שהערכים שלו ישמרו בCB.

בעקרון אם אתה ממש רוצה לעשות את זה בצורה ערבית אתה יכול לייצור 2 render targets אחת ל2D ואחת ל3D ואז לעשות blending עם שניהם, רק תדאג שהAlpha של ה2D של כל פיקסל שלא מכיל מסגרת הוא 0.

כפי שכבר אמרתי אפילו מאומת בFAQ של הOpenGL בעצמו:

Subject 9.02: What is the best way to draw 2D overlays?

The best way is to use an orthographic projection and render the

overlays as texture mapped quads. If you want areas of the quads

to be transparent the textures should be RGBA with the alpha used

to create areas of transparency.

.

כמו שהסברתי בהתחלה, לייצור מרובע ולמפות אליו טקסטורה בהטלה אורטוגרפטית.

פורסם
  • מחבר

טוב הבנתי, אם זה ככה אז אני כבר אשאיר לבינתיים את מה שעשיתי בהתחלה כי את הנושא של טקסטורות אני עדיין לא מבין מספיק טוב.

תודה על העזרה וצפו פגיעה לעוד שאלות ;)

פורסם

אולי זה קשור יותר לדיון השני, אבל בDX אפשר לעשות את זה בלי בעיות מיוחדות.

פורסם

גם בopengl אין יותר מידי בעיות, הדרך לא עד כדי כך שונה פשוט בDX יש כמה פונקציות לדברים ספציפיים, אני פשוט לא מבין למה מחפשים 50 אלף דרכים בשביל להחליף נורה.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים