Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.191.189.120] |
|
Сообщ.
#1
,
|
|
|
Добрый день. Такой вопрос: имеется некий код, отображающий произвольную кривую посредством TRIANGLES_STRIP, необходимо подсвечивать зоны самопересечения. Варианта два:
1) городить огород и вычислять точки пересечения, добавлять нужные вершины и цвета, ... 2) использовать смешивание цветов. Проблема в том, что цвет один и glBlendFunc() на выходе дает исходный цвет. Что логично и так должно быть. Я пока не могу найти адекватного решения данной проблемы. Но, полагаю, что не я первый с этим сталкиваюсь. Если есть опыт или идеи - прошу поделиться. Возможно нужно просто написать хитрей шейдер и будет мне счастье. |
Сообщ.
#2
,
|
|
|
glStencilFunc + glStencilOp.
|
Сообщ.
#3
,
|
|
|
А можно и без стенсила обойтись, альфаканал задействовать.
|
Сообщ.
#4
,
|
|
|
OpenGL, а можно чуть подробнее? с учетом того, что с openGL я работаю без году неделю.
у меня есть следующий код: initGL: void SnowGlWidget::initializeGL() { glEnable(GL_DEPTH_TEST); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glStencilMask(0x00); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilMask(0xFF); QGLShader vShader(QGLShader::Vertex); if(!vShader.compileSourceCode( "attribute vec3 vertexPosition;\n" "uniform mat4 modelViewProjMatrix;\n" "attribute highp vec4 vertexAttr;\n" "attribute lowp vec4 colorAttr;\n" "varying lowp vec4 color;\n" "void main()\n" "{\n" "color = colorAttr;\n" "gl_Position = modelViewProjMatrix * vec4(vertexPosition, 1.0);\n" "}\n" )) { return; } QGLShader fShader(QGLShader::Fragment); if(!fShader.compileSourceCode( "varying lowp vec4 color;\n" "void main()\n" "{\n" " gl_FragColor = color;\n" "}\n" )) { QMessageBox::critical(0, tr("ERROR"), fShader.log(), QMessageBox::Ok); return; } if(!m_program.addShader(&vShader)){ return; } if(!m_program.addShader(&fShader)){ return; } if (!m_program.link()) { return; } if (!m_program.bind()) { return; } m_vertexAttr = m_program.attributeLocation("vertexAttr"); m_colorAttr = m_program.attributeLocation("colorAttr"); m_track = new SnowTrack(&m_program, m_vertexAttr, m_colorAttr, m_points); m_perspective.aspectRatio = height() > 0.0f ? float(width()) / float(height()) : 1.0f; } paintGL: void SnowGlWidget::paintGL() { qglClearColor(QColor(32,64,128,0)); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glStencilMask(0x00); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilMask(0xFF); m_projectionMat.setToIdentity(); m_projectionMat.perspective( m_perspective.verticalAngle, m_perspective.aspectRatio, m_perspective.nearPlane, m_perspective.farPlane); m_viewMat.setToIdentity(); m_viewMat.lookAt(m_lookAt.eye, m_lookAt.center, m_lookAt.up); m_modelMat.setToIdentity(); m_modelMat.scale(m_modelScale); m_modelMat.rotate(m_angle,-0.f,0.f,1); m_modelMat.translate(m_modelTranslation); m_program.setUniformValue("normalMatrix", m_modelMat.normalMatrix()); // world normal m_program.setUniformValue("modelViewMatrix", m_viewMat * m_modelMat); m_program.setUniformValue("projectionMatrix", m_projectionMat); m_program.setUniformValue("modelViewProjMatrix", m_projectionMat * m_viewMat * m_modelMat); m_program.setUniformValue("lightPosition", m_lightPosition); m_program.setUniformValue("lightKd", m_lightKd); m_program.setUniformValue("lightLd", m_lightLd); m_track->draw(); calculateFps(); } формирование вершин и цветов для шейдера void SnowTrack::drawTest() { m_vertices << -0.5f << -0.5f << 0.0f; m_vertices << 0.5f << -0.5f << 0.0f; m_vertices << 0.0f << 0.5f << 0.0f; m_vertices << -0.2f << -0.5f << 0.0f; m_vertices << 0.8f << -0.5f << 0.0f; m_vertices << 0.2f << 0.5f << 0.0f; m_colors << 0.f << 1.f << 0.f; m_colors << 0.f << 1.f << 0.f; m_colors << 0.f << 1.f << 0.f; m_colors << 1.f << 1.f << 0.f; m_colors << 1.f << 1.f << 0.f; m_colors << 1.f << 1.f << 0.f; } ну и собственно отрисовка void SnowTrack::draw() { m_program->enableAttributeArray("vertexPosition"); m_program->setAttributeArray("vertexPosition", m_vertices.data(), 3); m_program->setAttributeArray(m_colorAttr, m_colors.data(), 3); m_program->enableAttributeArray(m_colorAttr); glDrawArrays(GL_TRIANGLE_STRIP, 0, m_vertices.size() / 3); m_program->disableAttributeArray(m_vertexAttr); m_program->disableAttributeArray(m_colorAttr); } и, судя по всему, я все же что-то делаю не так, ибо получаю следующую картинку Прикреплённая картинка
Добавлено Mikle, наверное можно, только пока не могу понять как. С учетом того, что мне нужно получать заданный цвет и трек у меня одного цвета. |
Сообщ.
#5
,
|
|
|
Цитата kotmatroskin55 @ мне нужно получать заданный цвет и трек у меня одного цвета Тогда лучше стенсил, именно заданный цвет получить сложнее с помощью альфы, можно получить просто контрастный, какой получится. |
Сообщ.
#6
,
|
|
|
Mikle
OpenGL, и все же таки, можно пример какой-нить? Для тех, кому сразу непонятен, например этот мануал. Мне бы маленькую зацепочку, а дальше я сам. |
Сообщ.
#7
,
|
|
|
Я могу только на Direct3D пример сделать, если поможет.
|
Сообщ.
#8
,
|
|
|
У меня готового примера нет, и когда сделаю - не могу сказать. Идея была в том, чтобы рисовать дважды - первый раз с функцией GL_ALWAYS и операцией GL_INCR (т.е. каждый раз увеличиваешь значение в буфере, там, где нарисуешь больше 1 раза будет значение, большее 1), а второй раз - цветом смешения и функцией GL_NOTEQUAL (т.е. рисуешь там, где не равно 1).
|
Сообщ.
#9
,
|
|
|
OpenGL
Цитата OpenGL @ У меня готового примера нет, и когда сделаю - не могу сказать. ну это не страшно, буду курить мануалы, а за идею спасибо. |
Сообщ.
#10
,
|
|
|
доброго всем дня. тема была заброшена, так как был занят более приоритетными задачами. теперь же руки дошли наконец. Но воз пока и ныне там. Т.е. не совсем. С помощью альфа-канала я очень даже умею подсвечивать пересечения. Тут особых проблем не возникло. А вот с заданием конкретного цвета - не могу понять в чем проблема.
void GlWidget::stencilIntersection() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); updateTransforms(); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);// отключили запись во все буферы glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);// включили увеличение стенсила при каждом пересечении drawTrack(m_trackColor);// отрисовали трек, причем, получается, что на каждом пересечении значение в стенсиле увеличилось на единичку, так? glStencilMask(0);// отключаем запись в стенсил glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 1, 0b111); m_trackColor = Qt::white;//там где стенисил единичка - рисуем белым drawTrack(m_trackColor);// отрисовали трек белым цветом glStencilFunc(GL_EQUAL, 2, 0b111); m_trackColor = Qt::red;// там где стенсил двоечка - рисуем бледно красным drawTrack(m_trackColor);// отрисовали трек glStencilFunc(GL_EQUAL, 3, 0b111); glClearStencil(0); m_trackColor = Qt::darkRed;// там где стенсил троечка - рисуем темно красным drawTrack(m_trackColor); drawCenterLine(); m_trackProgram.bind(); calculateFps(); } то есть, по идее алгоритм должен быть примерно таким. однако на выходе получаю черный экран. Почему - понятно glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);// отключили запись во все буферы |
Сообщ.
#11
,
|
|
|
эти результаты я получил с помощью glBlend
Прикреплённая картинка
Прикреплённая картинка
|
Сообщ.
#12
,
|
|
|
в общем проблему решить получилось, спасибо коллегам с gamedev, тут описание решения, если кому интересно, могу поделиться реализацией.
|