Добро пожаловать! Это — архивная версия форумов на «Хакер.Ru». Она работает в режиме read-only.
 

c++ && openGL. Масштабирование в противофазе

Пользователи, просматривающие топик: none

Зашли как: Guest
Все форумы >> [Компилируемые языки] >> c++ && openGL. Масштабирование в противофазе
Имя
Сообщение << Старые топики   Новые топики >>
c++ && openGL. Масштабирование в противофазе - 2010-10-24 22:46:05.893333   
oneTrouble

Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
Необходима помощь по преобразованию проги, то бишь не пойму куда дальше двигать.
Задача - есть две фигуры(прямоугольник и треугольник) По нажатию ЛКМ они масштабируются в противофазе, до нажатия ПКМ.
Собственно, реализовал только масштабирование фигур в противофазе с помощью цикла и матриц преобразования. Фигуры масштабируются относительно середины основания.
Суть вопроса - как заставить фигуры масштабироваться бесконечно до тех пор пока не нажата ПКМ и прерывать цикл сразу после нажатия ПКМ? Прошу помощи/совета.

#include &lt;GL/glut.h&gt; #include &lt;stdlib.h&gt; #include &lt;math.h&gt; #include &lt;windows.h&gt; #define PI 3.1459 GLfloat R=880.0/640; GLfloat w=40 ; GLfloat h; GLfloat a,s; GLfloat l, r, b, t; bool scale=false; void init(void) { h=w/R; l=-w/2; r=w/2; b=-h/2; t=h/2; glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(l, r, b, t); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void showAxis(void) { glColor3f(0.0f,0.0f,1.0f); glBegin(GL_LINES); glVertex2f(0,0); glVertex2f(0,t); glVertex2f(0,0); glVertex2f(r,0); glEnd(); } void fig0(void) { glColor3f(1,1,1); glBegin(GL_LINE_LOOP); glVertex2f(-3,0); glVertex2f(-3,3); glVertex2f(3,3); glVertex2f(3,0); glEnd(); } void fig1(void) { glColor3f(1,1,1); glBegin(GL_LINE_LOOP); glVertex2f(-2,0); glVertex2f(0,5); glVertex2f(2,0); glEnd(); } void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { scale = true; } if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP) { scale = false; } glutPostRedisplay(); } void scene(void) { //default position figures glClear(GL_COLOR_BUFFER_BIT); showAxis(); //fig1 glPushMatrix(); glTranslatef(15,0,0); glScalef(1.2,1.2,0); fig1(); glPopMatrix( ); //fig0 glPushMatrix(); glTranslatef(7.2,0,0); glScalef(1.2,1.2,0); fig0(); glPopMatrix( ); glFlush(); glutSwapBuffers(); //scale + for(a=1.2,s=1.2;a&lt;=2.3 && s&gt;=0 && scale!=false;a+=0.1,s-=0.1) { glClear(GL_COLOR_BUFFER_BIT); showAxis(); //fig1 glPushMatrix(); glTranslatef(15,0,0); glScalef(a,a,0); fig1(); glPopMatrix( ); //fig0 glPushMatrix(); glTranslatef(7.2,0,0); glScalef(s,s,0); fig0(); glPopMatrix( ); glFlush(); glutSwapBuffers(); Sleep(200); } //scale - for(a=2.3,s=0.1;a&gt;=0 && s&lt;=2.3 && scale!=false;a-=0.1,s+=0.1) { glClear(GL_COLOR_BUFFER_BIT); showAxis(); //fig1 glPushMatrix(); glTranslatef(15,0,0); glScalef(a,a,0); fig1(); glPopMatrix( ); //fig0 glPushMatrix(); glTranslatef(7.2,0,0); glScalef(s,s,0); fig0(); glPopMatrix( ); glFlush(); glutSwapBuffers(); Sleep(200); } //scale do default position for(a=0.1,s=2.3;a&lt;=1.3 && s&gt;=1.3 && scale!=false;a+=0.1,s-=0.1) { glClear(GL_COLOR_BUFFER_BIT); showAxis(); //fig1 glPushMatrix(); glTranslatef(15,0,0); glScalef(a,a,0); fig1(); glPopMatrix( ); //fig0 glPushMatrix(); glTranslatef(7.2,0,0); glScalef(s,s,0); fig0(); glPopMatrix( ); glFlush(); glutSwapBuffers(); Sleep(200); } } void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGB); glutInitWindowSize(640,480); glutInitWindowPosition(20,20); glutCreateWindow("scale"); glutDisplayFunc(scene); glutMouseFunc(mouse); init(); glutMainLoop(); }
При цикле while(scale!=false) - перед тремя for - получается бесконечный цикл и на нажатие ПКМ не реагирует. Пробовал в каждый цикл for вставлять условие if(scale==false) { break; показ фигур в дефолтном состоянии} но цикл не прерывается на конкретной итерации после нажатия ПКМ, прерывается только после прохождения всех итераций циклов for. Не могу додуматься как все это реализовать(
P.S пишу в VS C++ 6.0.
Post #: 1
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-24 23:39:36.680000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
Один вызов DisplayFunc должен рисовать один раз. Пока ты гоняешь цикл в DisplayFunc ты не даёшь главному циклу glut ничего делать, в том числе и принимать ввод мышки.
Напиши функцию, которая будет выполнять одну итерацию масштабирования и инициировать перерисовку при помощи glutPostRedisplay. Если хочется, твоя функция может выполнять итерацию масштабирования условно: делаем проверку времени, и если пора выполнять итерацию то выполняем; иначе return – возвращаем управление. А потом открой для себя функцию glutIdleFunc, скорми ей свою функцию-итерацию, и собственно всё.
Post #: 2
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-24 23:57:02.526666   
oneTrouble

Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
спасиб за ответ. завтра осмыслю и буду исправлять.
Post #: 3
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-26 00:49:48.863333   
oneTrouble

Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
С одной итерацией все получается
void fscale() { if(scale != false){ if(a&lt;=2.3 && s&gt;=0.1) { a+=0.1; s-=0.1; glClear(GL_COLOR_BUFFER_BIT); showAxis(); glPushMatrix(); glTranslatef(15,0,0); glScalef(a,a,0); fig1(); glPopMatrix( ); glPushMatrix(); glTranslatef(7.2,0,0); glScalef(s,s,0); fig0(); glPopMatrix( ); glFlush(); glutSwapBuffers(); Sleep(200); } } } void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGB); glutInitWindowSize(640,480); glutInitWindowPosition(20,20); glutCreateWindow("scale"); glutDisplayFunc(scene); glutIdleFunc(fscale); glutMouseFunc(mouse); init(); glutMainLoop(); } То есть 1ая итерация уменьшает прямоугольник и увеличивает треугольник, теперь необходимо чтобы прямоугольник увеличивался, а треугольник уменьшался. В одной итерации это сделать не удалось(пытался условие менять) Это можно сделать в одной итерации?
Или написать вторую итерацию отдельной функцией? И как потом ее связать с glutIdleFunc()? И если можно пожалуйста поподробнее про использовании glutPostRedisplay().
Post #: 4
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-26 07:45:33.440000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
http://www.opengl.org/resources/libraries/glut/spec3/node63.html
http://www.opengl.org/resources/libraries/glut/spec3/node20.html
Закидываешь в Idle callbacka+=0.1; s-=0.1; glutPostRedisplay (); В Display callback'е оставляешь только отрисовку.
Post #: 5
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-26 21:19:02.390000   
oneTrouble

Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
void scene(void) { glClear(GL_COLOR_BUFFER_BIT); showAxis(); glPushMatrix(); glTranslatef(15,0,0); glScalef(a,a,0); fig1(); glPopMatrix( ); glPushMatrix(); glTranslatef(7.2,0,0); glScalef(s,s,0); fig0(); glPopMatrix( ); glFlush(); glutSwapBuffers(); Sleep(200); } void fscale() { if(scale != false) { a+=0.1;s-=0.1; glutPostRedisplay (); } } void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGB); glutInitWindowSize(640,480); glutInitWindowPosition(20,20); glutCreateWindow("scale"); glutDisplayFunc(scene); glutIdleFunc(fscale); glutMouseFunc(mouse); init(); glutMainLoop(); } поправил, но это ничего не меняет. При простом добавлении
a+=0.1; s-=0.1; glutPostRedisplay (); в Idle callback
Получается:
">
Из скрина видно что фигуры выходят за пределы окна.
Каким путем достичь того чтобы прорисовывалось масштабирование например от if(a<=2.3 && s>=0.1) a+=0.1; s-=0.1; , а потом наоборот if(a>0.1 && s<2.3) a-=0.1; s+=0.1;
Пробовал так:
вvoid fscale() { if(scale != false) { if((a&lt;=2.3 && s&gt;=0.1) a+=0.1;s-=0.1; glutPostRedisplay (); } }
Все отрисовывается до заданных пределов.То есть масштабирует один цикл - треуг. увеличивается, прямоуг. уменьшается. Не могу заставить их продолжить масштабироваться. Вторую итерацию не могу сделать (условие if(a>0.1 && s<2.3) не подходит)
Вполне возможно что я чего то не просёк, прошу еще раз обьяснить эту ситуацию.
Post #: 6
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-26 23:24:51.850000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
void fscale() { if(scale != false) { if(a&lt;=2.3 && s&gt;=0.1) { a+=0.1; s-=0.1; } else { a -= .1; s += .1; } glutPostRedisplay (); } }
Post #: 7
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-26 23:39:31.273333   
oneTrouble

Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
не работает, увеличивает уменьшает на 0.1 и после сразу же уменьшает и увеличивает. то есть вся эта конструкция дрыгается до ПКМ.
Post #: 8
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-27 00:32:40.463333   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
Ну запусти ты программу под дебуггером. Поставь бряк на fscale, пошагово дойди до выхода из fscale и дай программе выполнятся самостоятельно. Она опять повиснет на бряке, ты опять оттрассируй функцию. Не забывай при этом разглядывать значения всех переменных, и думать понемногу. Продолжай трассировать fscale до полного просветления.
Там условие должно быть посложнее. Ты его на русском сформулируй: при каких условиях a увеличивается, а при каких уменьшается. Там ведь всё не так просто, недостаточно сказать, что если a < 2.3 то увеличиваем a, иначе уменьшаем. Ты видел результат. a быстренько добежит до значения близкого к 2.3, и будет прыгать вокруг него. Надо чтобы a увеличивалось до какого-то значения, потом уменьшалось до другого. То есть,ЕСЛИ а увеличивается, и ЕСЛИ a &lt; max_a, то увеличиваем a, ИНАЧЕ уменьшаем a и запоминаем, что a уменьшается; ИНАЧЕ (если a уменьшается) и ЕСЛИ a &gt; min_a, то уменьшаем a, ИНАЧЕ увеличиваем a и запоминаем, что а увеличивается. Тебе придётся ещё хранить в отдельной переменной текущее изменение: надо знать увеличивается a или уменьшается. Можно сделать иначе: завести переменную da = 0.1. И написать, что-то типа:if (scale) { if (a + da &gt;= max_a || a + da &lt;= min_a) { da = -da; } a += da; }
Post #: 9
RE: c++ && openGL. Масштабирование в противофазе - 2010-11-06 19:21:53.713333   
oneTrouble

Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
спасибо, rgo. Решение нашел с помощью сообщества ubuntu и немного другим способом.
Post #: 10
Страниц:  [1]
Все форумы >> [Компилируемые языки] >> c++ && openGL. Масштабирование в противофазе







Связаться:
Вопросы по сайту / xakep@glc.ru

Предупреждение: использование полученных знаний в противозаконных целях преследуется по закону.