c++ && openGL. Масштабирование в противофазе
Пользователи, просматривающие топик: none
|
Зашли как: Guest
|
Имя |
Сообщение |
<< Старые топики Новые топики >> |
|
|
c++ && openGL. Масштабирование в противофазе - 2010-10-24 22:46:05.893333
|
|
|
oneTrouble
Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
|
Необходима помощь по преобразованию проги, то бишь не пойму куда дальше двигать. Задача - есть две фигуры(прямоугольник и треугольник) По нажатию ЛКМ они масштабируются в противофазе, до нажатия ПКМ. Собственно, реализовал только масштабирование фигур в противофазе с помощью цикла и матриц преобразования. Фигуры масштабируются относительно середины основания. Суть вопроса - как заставить фигуры масштабироваться бесконечно до тех пор пока не нажата ПКМ и прерывать цикл сразу после нажатия ПКМ? Прошу помощи/совета. #include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#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<=2.3 && s>=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>=0 && s<=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<=1.3 && s>=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.
|
|
|
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, скорми ей свою функцию-итерацию, и собственно всё.
|
|
|
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-24 23:57:02.526666
|
|
|
oneTrouble
Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
|
спасиб за ответ. завтра осмыслю и буду исправлять.
|
|
|
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<=2.3 && s>=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().
|
|
|
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'е оставляешь только отрисовку.
|
|
|
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<=2.3 && s>=0.1)
a+=0.1;s-=0.1;
glutPostRedisplay ();
}
} Все отрисовывается до заданных пределов.То есть масштабирует один цикл - треуг. увеличивается, прямоуг. уменьшается. Не могу заставить их продолжить масштабироваться. Вторую итерацию не могу сделать (условие if(a>0.1 && s<2.3) не подходит) Вполне возможно что я чего то не просёк, прошу еще раз обьяснить эту ситуацию.
|
|
|
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<=2.3 && s>=0.1) {
a+=0.1;
s-=0.1;
} else {
a -= .1;
s += .1;
}
glutPostRedisplay ();
}
}
|
|
|
RE: c++ && openGL. Масштабирование в противофазе - 2010-10-26 23:39:31.273333
|
|
|
oneTrouble
Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
|
не работает, увеличивает уменьшает на 0.1 и после сразу же уменьшает и увеличивает. то есть вся эта конструкция дрыгается до ПКМ.
|
|
|
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 < max_a, то
увеличиваем a,
ИНАЧЕ уменьшаем a и запоминаем, что a уменьшается;
ИНАЧЕ (если a уменьшается)
и ЕСЛИ a > min_a, то
уменьшаем a,
ИНАЧЕ увеличиваем a и запоминаем, что а увеличивается. Тебе придётся ещё хранить в отдельной переменной текущее изменение: надо знать увеличивается a или уменьшается. Можно сделать иначе: завести переменную da = 0.1. И написать, что-то типа:if (scale) {
if (a + da >= max_a || a + da <= min_a) {
da = -da;
}
a += da;
}
|
|
|
RE: c++ && openGL. Масштабирование в противофазе - 2010-11-06 19:21:53.713333
|
|
|
oneTrouble
Сообщений: 31
Оценки: 0
Присоединился: 2009-02-27 23:46:41.190000
|
спасибо, rgo. Решение нашел с помощью сообщества ubuntu и немного другим способом.
|
|
|
|
|