Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > [OpenGL] Цвет и GL_FRONT_AND_BACK.


Автор: Elfet 10.2.2010, 15:11
Всем привет! 

Подскажите, пожалуйста, почему у меня разукрашивается только одна сторона треугольника?

Код

    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
    glBegin(GL_TRIANGLES);
    glColor4d(0.8, 0.1, 0.0, 1.0);
    glVertex3d(0.0, 0.0, 0.0);
    glColor4d(0.0, 0.8, 0.2, 1.0);
    glVertex3d(0.0, 1.0, 0.0);
    glColor4d(0.2, 0.2, 1.0, 1.0);
    glVertex3d(1.0, 0.0, 0.0);
    glEnd();


А остальная остаётся чёрной? Хотя я указываю GL_FRONT_AND_BACK?

И ещё как понять где расположен источник света? Мне нужно что бы он был там где и камера.
Код

void Render3D::initializeGL()
{
    static const GLfloat lightPos[4] = { 0.0f, 0.0f, 10.0f, 1.0f };

    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glEnable ( GL_COLOR_MATERIAL );

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_NORMALIZE);
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}


Заранее спасибо!

Автор: kemiisto 10.2.2010, 15:25
Цитата(Elfet @  10.2.2010,  16:11 Найти цитируемый пост)
Мне нужно что бы он был там где и камера.

Если ты работаешь со стандартным OpenGL, то какая нафиг камера? smile 

Если есть свой класс обёртка для камеры - в студию. Хотя...

Если пишешь на Qt и нужна камера-трекбол - используй http://www.libqglviewer.com/. Базовые потребности он удовлетворяет. smile 

Автор: Elfet 10.2.2010, 15:58
Да, я использую Qt. Но мне нужно бы самому бы всё сделать. Камера у меня немного другая будет. 

Вот мой код:
Код

#include "Render3D.h"

Render3D::Render3D(QWidget *parent)
    : QGLWidget(parent)
{
    mooving = false;
    distanceToSection = 0;

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(Render()));
    timer->start(20);
}

Render3D::~Render3D()
{
    delete timer;
}

void Render3D::Render()
{
    updateGL();
}

void Render3D::setXRotation(int angle)
{
    normalizeAngle(&angle);
    if (angle != xRot) {
        xRot = angle;
        emit xRotationChanged(angle);
        updateGL();
    }
}

void Render3D::setYRotation(int angle)
{
    normalizeAngle(&angle);
    if (angle != yRot) {
        yRot = angle;
        emit yRotationChanged(angle);
        updateGL();
    }
}

void Render3D::setZRotation(int angle)
{
    normalizeAngle(&angle);
    if (angle != zRot) {
        zRot = angle;
        emit zRotationChanged(angle);
        updateGL();
    }
}

void Render3D::setDistanceToSection(int d)
{
    distanceToSection = d;
    updateGL();
}

void Render3D::normalizeAngle(int *angle)
{
    while (*angle < 0)
        *angle += 360 * 16;
    while (*angle > 360 * 16)
        *angle -= 360 * 16;
}

void Render3D::initializeGL()
{
    static const GLfloat lightPos[4] = { 0.0f, 0.0f, 10.0f, 1.0f };

    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glEnable ( GL_COLOR_MATERIAL );

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_NORMALIZE);
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

void Render3D::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
    glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
    glRotated(zRot / 16.0, 0.0, 0.0, 1.0);

    if(mooving)
    {
        drawAxes();
    }
    else
    {
        drawAxes();

        glTranslated(distanceToSection, 0.0, 0.0);

        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glBegin(GL_TRIANGLES);
        glColor4d(0.8, 0.1, 0.0, 1.0);
        glVertex3d(0.0, 0.0, 0.0);
        glColor4d(0.0, 0.8, 0.2, 1.0);
        glVertex3d(0.0, 1.0, 0.0);
        glColor4d(0.2, 0.2, 1.0, 1.0);
        glVertex3d(1.0, 0.0, 0.0);
        glEnd();
    }

    glPopMatrix();
}

void Render3D::drawAxes()
{
    glDisable(GL_LIGHTING);

    glColor4d(0.8, 0.1, 0.0, 1.0);
    glBegin(GL_LINES);
    glNormal3d(1,0,0);
    glVertex3d(-1000.0, 0.0, 0.0);
    glVertex3d(1000.0, 0.0, 0.0);
    glEnd();

    glColor4d(0.0, 0.8, 0.2, 1.0);
    glBegin(GL_LINES);
    glNormal3d(0,1,0);
    glVertex3d(0.0, -1000.0, 0.0);
    glVertex3d(0.0, 1000.0, 0.0);
    glEnd();

    glColor4d(0.2, 0.2, 1.0, 1.0);
    glBegin(GL_LINES);
    glNormal3d(0,0,1);
    glVertex3d(0.0, 0.0, -1000.0);
    glVertex3d(0.0, 0.0, 1000.0);
    glEnd();

    glEnable(GL_LIGHTING);
}

void Render3D::resizeGL(int width, int height)
{
    int side = qMax(width, height);
    glViewport((width - side) / 2, (height - side) / 2, side, side);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, +1.0, -1.0, 1.0, 1.0, 1000.0); // glOrtho
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslated(0.0, 0.0, -10.0);
}

void Render3D::mousePressEvent(QMouseEvent *event)
{
    lastPos = event->pos();
    mooving = true;
}

void Render3D::mouseMoveEvent(QMouseEvent *event)
{
    int dx = event->x() - lastPos.x();
    int dy = event->y() - lastPos.y();

    if(event->buttons() & Qt::MidButton) {
        setDistanceToSection(distanceToSection + dy / 10.);
    }
    else if (event->buttons() & Qt::LeftButton) {
        setXRotation(xRot + 8 * dy);
        setYRotation(yRot + 8 * dx);
    } else if (event->buttons() & Qt::RightButton) {
        setXRotation(xRot + 8 * dy);
        setZRotation(zRot + 8 * dx);
    }
    lastPos = event->pos();
}

void Render3D::mouseReleaseEvent(QMouseEvent *event)
{
    mooving = false;
}


Автор: kemiisto 10.2.2010, 16:30
Я когда-то тоже http://forum.vingrad.ru/forum/topic-254020.html занимался. Впустую, замечу. smile К сожалению, у меня не сохранилось исходников...

Фуф, так. Ну, насколько я вижу, надо перенести, всё что связано со светом из initializeGL() в paintGL() после всех glRotated(). Но могу и ошибаться. Т.е. надо повернуть систему координат и уже в изменённой поставить свет. Вроде так. Попробуй.

Добавлено через 8 минут и 3 секунды
Странноватый код у тебя в paintGL()...

Обычно:
Код

void Render3D::paintGL()
{
    //Чистим экран и буфер глубины
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //Сбрасываем матрицу
    glLoadIdentity();
    //Рисуем
    ...
}


Не нравиццо мне glPushMatrix(); / glPopMatrix(); в коде для отрисовки. Попробуй убрать их, а свет не переносить.

Добавлено через 11 минут и 5 секунд
Последняя моя мысль кажеться мне правильной. Откуда дровишкикод?

Автор: Elfet 10.2.2010, 22:33
Код из примеров по работе с opengl из qt-та smile

Если их убрать, то всё начинает лихорадочно вращаться smile

Добавлено через 1 минуту и 26 секунд
Цвет есть у стороны если ось z смотрит на камеру, и чёрный полигон, если она смотрит против.

Автор: kemiisto 10.2.2010, 22:39
Цитата(Elfet @  10.2.2010,  23:33 Найти цитируемый пост)
Цвет есть у стороны если ось z смотрит на камеру, и чёрный полигон, если она смотрит против.

А если 
Цитата(kemiisto @  10.2.2010,  17:30 Найти цитируемый пост)
перенести, всё что связано со светом из initializeGL() в paintGL() после всех glRotated()

?

Автор: Elfet 10.2.2010, 22:44
Добился того что полигон одинакового цвета, перенеся определение источника цвета на ось z. Но это не очень удобно, мне же нужно задать источник света там где камера.

Код

void Render3D::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();
    glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
    glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
    glRotated(zRot / 16.0, 0.0, 0.0, 1.0);

    static const GLfloat lightPos[4] = { 0.0f, 0.0f, 10.0f, 0.0f };

    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

    if(mooving)
    {
        drawAxis(5);
    }
    else
    {
        drawAxes();        

        glTranslated(distanceToSection, 0.0, 0.0);

        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glBegin(GL_TRIANGLES);
        glColor4d(0.8, 0.1, 0.0, 1.0);
        glVertex3d(0.0, 0.0, 0.0);
        glColor4d(0.0, 0.8, 0.2, 1.0);
        glVertex3d(0.0, 1.0, 0.0);
        glColor4d(0.2, 0.2, 1.0, 1.0);
        glVertex3d(1.0, 0.0, 0.0);
        glEnd();
    }

    glPopMatrix();
}


Добавлено через 7 минут и 26 секунд
Странно, что цвет есть только с одной стороны, куда нормаль смотрит: glNormal3d(0,0,-1);
Но я ведь указываю GL_FRONT_AND_BACK!!! Может косяк какой?

Автор: Quartz 20.2.2010, 23:40
Код

glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)