QVector3D ExtraMath::mouse_raycast(int mx, int my, int width, int height, float invertedy, QMatrix4x4 view_matrix, QMatrix4x4 projection_matrix) { // normalize the x-mouse position float nx = (2.0f * mx) / width - 1.0f; // normalize the y-mouse position float ny = invertedy*(1.0f - (2.0f * my) / height); // clip the x,y,z values between -1:1 QVector4D ray_clip = QVector4D(nx, ny, -1, 1.0); // invert the projection QMatrix4x4 pInverse = projection_matrix.inverted(NULL); // invert the view QMatrix4x4 vInverse = view_matrix.inverted(NULL); // "convert" the normalized ray to the projection values QVector4D ray_eye = pInverse*ray_clip; // change the w-value of the vector for matrix manipulation purposes ray_eye = QVector4D(ray_eye.x(), ray_eye.y(), -1.0, 0); // "convert" the new ray to the view values QVector4D ray_wor4 = vInverse*ray_eye; // take the x,y,z values of the new position QVector3D ray_wor = ray_wor4.toVector3D(); ray_wor.normalize(); // make the ray a unit vector // return the raycast of the 2D mouse in the 3D world view projection return ray_wor; }
int GLWidget::glhUnProjectf(float& winx, float& winy, float& winz, QMatrix4x4& modelview, QMatrix4x4& projection, QVector4D& objectCoordinate) { //Transformation matrices QVector4D in,out; //Calculation for inverting a matrix, compute projection x modelview //and store in A[16] QMatrix4x4 A = projection * modelview; //Now compute the inverse of matrix A QMatrix4x4 m = A.inverted(); //Transformation of normalized coordinates between -1 and 1 in[0]=(winx)/(float)width()*2.0-1.0; in[1]=(1-(winy)/(float)height())*2.0-1.0; in[2]=2.0*winz-1.0; in[3]=1.0; //Objects coordinates out = m * in; if(out[3]==0.0) return 0; out[3]=1.0/out[3]; objectCoordinate[0]=out[0]*out[3]; objectCoordinate[1]=out[1]*out[3]; objectCoordinate[2]=out[2]*out[3]; return 1; }
QUniformValue *RenderView::inverseProjectionMatrix(const QMatrix4x4 &) const { QMatrix4x4 projection; if (m_data->m_renderCamera) projection = m_data->m_renderCamera->projection(); return QUniformValue::fromVariant(projection.inverted(), m_allocator); }
void Scene::draw(const Camera& camera, QOpenGLShaderProgram* program, int uniformsFlags, bool bindProgram) const { if(!_models or !_painter) { debugWarning("Null scene or painter not set."); return; } if(bindProgram) program->bind(); if(uniformsFlags & ViewMatrix) program->setUniformValue("viewMatrix", camera.viewMatrix()); if(uniformsFlags & ViewInvMatrix) program->setUniformValue("viewInvMatrix", camera.viewMatrix().inverted()); if(uniformsFlags & ProjMatrix) program->setUniformValue("projMatrix", camera.projMatrix()); if(uniformsFlags & ProjInvMatrix) program->setUniformValue("projInvMatrix", camera.projMatrix().inverted()); QList<QGLSceneNode*> nodes= _models->allChildren(); nodes << _models; foreach(QGLSceneNode* n, nodes) { if(!n->count()) continue; const QMatrix4x4 modelMatrix= n->localTransform(); if(uniformsFlags & ModelMatrix) program->setUniformValue("modelMatrix", modelMatrix); if(uniformsFlags & ModelInvMatrix) program->setUniformValue("modelInvMatrix", modelMatrix.inverted()); if(uniformsFlags & ModelITMatrix) program->setUniformValue("modelITMatrix", modelMatrix.inverted().transposed()); if(uniformsFlags & MVPMatrix) program->setUniformValue("mvpMatrix", camera.projMatrix() * camera.viewMatrix() * modelMatrix); n->material()->bind(_painter); n->geometry().draw(_painter, n->start(), n->count()); } if(bindProgram) program->release(); }
QUniformValue *RenderView::inverseViewportMatrix(const QMatrix4x4 &model) const { Q_UNUSED(model); QMatrix4x4 viewportMatrix; viewportMatrix.viewport(resolveViewport(*m_viewport, m_surfaceSize)); QMatrix4x4 inverseViewportMatrix = viewportMatrix.inverted(); return QUniformValue::fromVariant(QVariant::fromValue(inverseViewportMatrix), m_allocator); }
void ViewportView::drawCoords(QPainter* painter) const { QPointF mouse_pos = mapToScene(mapFromGlobal(QCursor::pos())); if (!sceneRect().contains(mouse_pos)) { return; } // Get rotate-only transform matrix QMatrix4x4 M = getMatrix(ROT); const float threshold = 0.98; const auto a = M.inverted() * QVector3D(0, 0, 1); QList<QPair<char, QVector3D>> axes = { {'x', QVector3D(1, 0, 0)}, {'y', QVector3D(0, 1, 0)}, {'z', QVector3D(0, 0, 1)}}; char axis = 0; float opacity = 0; for (const auto v : axes) { float dot = fabs(QVector3D::dotProduct(a, v.second)); if (dot > threshold) { axis = v.first; opacity = (dot - threshold) / (1 - threshold); } } auto p = sceneToWorld(mouse_pos); int value = opacity * 200; painter->setPen(QPen(QColor(255, 255, 255, value))); QString txt; if (axis == 'z') { txt = QString("X: %1\nY: %2").arg(p.x()).arg(p.y()); } else if (axis == 'y') { txt = QString("X: %1\nZ: %2").arg(p.x()).arg(p.z()); } else if (axis == 'x') { txt = QString("Y: %1\nZ: %2").arg(p.y()).arg(p.z()); } painter->drawText({-width()/2.0 + 10, -height()/2.0 + 10, 300, 200}, txt); }
/** \brief When a station has been selected, this updates the shot lines This shows the shot lines from the selected station. If no station is currently selected, this will hide the lines */ void cwScrapStationView::updateShotLines() { if(scrap() == nullptr) { return; } if(scrap()->parentNote() == nullptr) { return; } if(scrap()->parentNote()->parentTrip() == nullptr) { return; } if(transformUpdater() == nullptr) { return; } cwNoteStation noteStation = scrap()->station(selectedItemIndex()); //Get the current trip cwNote* note = scrap()->parentNote(); cwTrip* trip = note->parentTrip(); cwCave* cave = trip->parentCave(); cwStationPositionLookup stationPositionLookup = cave->stationPositionLookup(); //Clear all the lines ShotLines.clear(); if(noteStation.isValid() && stationPositionLookup.hasPosition(noteStation.name())) { QString stationName = noteStation.name(); QSet<cwStation> neighboringStations = trip->neighboringStations(stationName); //The position of the selected station QVector3D selectedStationPos = stationPositionLookup.position(noteStation.name()); //Create the matrix to covert global position into note position QMatrix4x4 noteTransformMatrix = scrap()->noteTransformation()->matrix(); //Matrix from page coordinates to cave coordinates noteTransformMatrix = noteTransformMatrix.inverted(); //From cave coordinates to page coordinates QMatrix4x4 notePageAspect = note->scaleMatrix().inverted(); //The note's aspect ratio QMatrix4x4 offsetMatrix; offsetMatrix.translate(-selectedStationPos); QMatrix4x4 dotPerMeter; dotPerMeter.scale(note->dotPerMeter(), note->dotPerMeter(), 1.0); QMatrix4x4 noteStationOffset; noteStationOffset.translate(QVector3D(noteStation.positionOnNote())); QMatrix4x4 toNormalizedNote = noteStationOffset * dotPerMeter * notePageAspect * noteTransformMatrix * offsetMatrix; //Go through all the neighboring stations and add the position to the line foreach(cwStation station, neighboringStations) { QVector3D currentPos = stationPositionLookup.position(station.name()); QVector3D normalizeNotePos = toNormalizedNote.map(currentPos); ShotLines.append(QLineF(noteStation.positionOnNote(), normalizeNotePos.toPointF())); }
/*! Maps \a point from viewport co-ordinates to eye co-ordinates. The size of the viewport is given by \a viewportSize, and its aspect ratio by \a aspectRatio. The returned vector will have its x and y components set to the position of the point on the near plane, and the z component set to -nearPlane(). This function is used for converting a mouse event's position into eye co-ordinates within the current camera view. */ QVector3D QGLCamera::mapPoint (const QPoint& point, float aspectRatio, const QSize& viewportSize) const { Q_D(const QGLCamera); // Rotate the co-ordinate system to account for the screen rotation. int x = point.x(); int y = point.y(); int width = viewportSize.width(); int height = viewportSize.height(); if (!d->adjustForAspectRatio) aspectRatio = 1.0f; if (d->screenRotation == 90) { if (aspectRatio != 0.0f) aspectRatio = 1.0f / aspectRatio; qSwap(x, y); qSwap(width, height); y = height - 1 - y; } else if (d->screenRotation == 180) { x = width - 1 - x; y = height - 1 - y; } else if (d->screenRotation == 270) { if (aspectRatio != 0.0f) aspectRatio = 1.0f / aspectRatio; qSwap(x, y); qSwap(width, height); } // Determine the relative distance from the middle of the screen. // After this xrel and yrel are typically between -1.0 and +1.0 // (unless the point was outside the viewport). The yrel is // flipped upside down to account for the incoming co-ordinate // being left-handed, but the world being right-handed. float xrel, yrel; if (width) xrel = ((float(x * 2)) - float(width)) / float(width); else xrel = 0.0f; if (height) yrel = -((float(y * 2)) - float(height)) / float(height); else yrel = 0.0f; // Reverse the projection and return the point in world co-ordinates. QMatrix4x4 m = projectionMatrix(aspectRatio); QMatrix4x4 invm = m.inverted(); return invm.map(QVector3D(xrel, yrel, -1.0f)); }
void BinghamRenderer::draw( QMatrix4x4 p_matrix, QMatrix4x4 mv_matrix, int width, int height, int renderMode, PropertyGroup& props ) { if ( renderMode != 1 ) // we are drawing opaque objects { // obviously not opaque return; } setRenderParams( props ); if ( m_orient == 0 ) { return; } m_pMatrix = p_matrix; m_mvMatrix = mv_matrix; initGeometry( props ); QGLShaderProgram* program = GLFunctions::getShader( "qball" ); program->bind(); program->setUniformValue( "u_alpha", 1.0f ); program->setUniformValue( "u_renderMode", renderMode ); program->setUniformValue( "u_canvasSize", width, height ); program->setUniformValue( "D0", 9 ); program->setUniformValue( "D1", 10 ); program->setUniformValue( "D2", 11 ); program->setUniformValue( "P0", 12 ); // Set modelview-projection matrix program->setUniformValue( "mvp_matrix", p_matrix * mv_matrix ); program->setUniformValue( "mv_matrixInvert", mv_matrix.inverted() ); program->setUniformValue( "u_hideNegativeLobes", m_minMaxScaling ); program->setUniformValue( "u_scaling", m_scaling ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIds[ 0 ] ); glBindBuffer( GL_ARRAY_BUFFER, vboIds[ 1 ] ); setShaderVars( props ); glDrawElements( GL_TRIANGLES, m_tris1, GL_UNSIGNED_INT, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); }
void SeaNode::draw(std::stack<QMatrix4x4> &MVStack, QMatrix4x4 cameraMatrix, QMatrix4x4 projectionMatrix, QOpenGLShaderProgram *shader) { QOpenGLShaderProgram *sh = Shaders::waterGeometryProgram; MVStack.push(MVStack.top()); MVStack.top().translate(this->translation); //Convert the quat to a matrix, may be a performance leak. QMatrix4x4 tempRot; tempRot.rotate(this->rotation.normalized()); MVStack.top() *= tempRot; //If the node is a leaf, draw its contents if(leaf) { Shaders::bind(sh); glUniformMatrix4fv(sh->uniformLocation("modelViewMatrix"), 1, GL_FALSE, MVStack.top().constData()); glUniformMatrix4fv(sh->uniformLocation("cameraInverseMatrix"), 1, GL_FALSE, cameraMatrix.inverted().constData()); glUniformMatrix4fv(sh->uniformLocation("perspectiveMatrix"), 1, GL_FALSE, projectionMatrix.constData()); glUniformMatrix4fv(sh->uniformLocation("normalMatrix"), 1, GL_FALSE, MVStack.top().inverted().transposed().constData()); int r = (id & 0x000000FF) >> 0; int g = (id & 0x0000FF00) >> 8; int b = (id & 0x00FF0000) >> 16; glUniform4f(sh->uniformLocation("id"), r/255.0f, g/255.0f, b/255.0f, 1.0f); glUniform4fv(sh->uniformLocation("color"), 1, color); struct timeval start; gettimeofday(&start, NULL); float seconds = ((start.tv_sec % (int) periodicity) + start.tv_usec / 1000000.0) / (periodicity / 4); glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_3D, noiseTexture); //glUniform1i(sh->uniformLocation("noiseTexture"), 5); glUniform1i(sh->uniformLocation("seaWidth"), seaWidth); glUniform1i(sh->uniformLocation("seaHeight"), seaHeight); glUniform1f(sh->uniformLocation("time"), seconds); this->primitive->draw(); Shaders::release(sh); } else {
void VolRenRaycastCuda::updateCUDALights(const QMatrix4x4& matView) { CudaLight cudaLights[10]; for (unsigned int i = 0; i < lights.size(); ++i) { QVector3D lightDir(matView.inverted() * QVector4D(lights[i].direction, 0.f)); lightDir.normalize(); cudaLights[i].direction.x = lightDir.x(); cudaLights[i].direction.y = lightDir.y(); cudaLights[i].direction.z = lightDir.z(); cudaLights[i].ambient.x = lights[i].color.x() * lights[i].ambient; cudaLights[i].ambient.y = lights[i].color.y() * lights[i].ambient; cudaLights[i].ambient.z = lights[i].color.z() * lights[i].ambient; cudaLights[i].diffuse.x = lights[i].color.x() * lights[i].diffuse; cudaLights[i].diffuse.y = lights[i].color.y() * lights[i].diffuse; cudaLights[i].diffuse.z = lights[i].color.z() * lights[i].diffuse; cudaLights[i].specular.x = lights[i].color.x() * lights[i].specular; cudaLights[i].specular.y = lights[i].color.y() * lights[i].specular; cudaLights[i].specular.z = lights[i].color.z() * lights[i].specular; cudaLights[i].shininess = lights[i].shininess; } cudaSetLights(lights.size(), cudaLights); }
// TODO: optimize for other color spaces void compute() const { recompute = false; //http://docs.rainmeter.net/tips/colormatrix-guide //http://www.graficaobscura.com/matrix/index.html //http://beesbuzz.biz/code/hsv_color_transforms.php // ?? const float b = brightness; // brightness R,G,B QMatrix4x4 B(1, 0, 0, b, 0, 1, 0, b, 0, 0, 1, b, 0, 0, 0, 1); // Contrast (offset) R,G,B const float c = contrast+1.0; const float t = (1.0 - c) / 2.0; QMatrix4x4 C(c, 0, 0, t, 0, c, 0, t, 0, 0, c, t, 0, 0, 0, 1); // Saturation const float wr = 0.3086f; const float wg = 0.6094f; const float wb = 0.0820f; float s = saturation + 1.0f; QMatrix4x4 S( (1.0f - s)*wr + s, (1.0f - s)*wg , (1.0f - s)*wb , 0.0f, (1.0f - s)*wr , (1.0f - s)*wg + s, (1.0f - s)*wb , 0.0f, (1.0f - s)*wr , (1.0f - s)*wg , (1.0f - s)*wb + s, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); // Hue const float n = 1.0f / sqrtf(3.0f); // normalized hue rotation axis: sqrt(3)*(1 1 1) const float h = hue*M_PI; // hue rotation angle const float hc = cosf(h); const float hs = sinf(h); QMatrix4x4 H( // conversion of angle/axis representation to matrix representation n*n*(1.0f - hc) + hc , n*n*(1.0f - hc) - n*hs, n*n*(1.0f - hc) + n*hs, 0.0f, n*n*(1.0f - hc) + n*hs, n*n*(1.0f - hc) + hc , n*n*(1.0f - hc) - n*hs, 0.0f, n*n*(1.0f - hc) - n*hs, n*n*(1.0f - hc) + n*hs, n*n*(1.0f - hc) + hc , 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); // B*C*S*H*rgb_range_mat(*yuv2rgb*yuv_range_mat)*bpc_scale M = B*C*S*H; // M *= rgb_range_translate*rgb_range_scale // TODO: transform to output color space other than RGB switch (cs_out) { case ColorSpace_XYZ: M = kXYZ2sRGB.inverted() * M; break; case ColorSpace_RGB: M *= ColorRangeRGB(ColorRange_Full, range_out); break; case ColorSpace_GBR: M *= ColorRangeRGB(ColorRange_Full, range_out); M = kGBR2RGB.inverted() * M; break; default: M = YUV2RGB(cs_out).inverted() * M; break; } switch (cs_in) { case ColorSpace_XYZ: M *= kXYZ2sRGB; break; case ColorSpace_RGB: break; case ColorSpace_GBR: M *= kGBR2RGB; break; default: M *= YUV2RGB(cs_in)*ColorRangeYUV(range_in, ColorRange_Full); break; } if (bpc_scale != 1.0 && cs_in != ColorSpace_XYZ) { // why no range correction for xyz? //qDebug("bpc scale: %f", bpc_scale); M *= QMatrix4x4(bpc_scale, 0, 0, 0, 0, bpc_scale, 0, 0, 0, 0, bpc_scale, 0, 0, 0, 0, a_bpc_scale ? bpc_scale : 1); // scale alpha channel too } //qDebug() << "color mat: " << M; }
QPoint CubeItem::cubeIntersection (QWidget *widget, const QPoint &point, int *actualFace) const { // Bail out if no scene. if (!mScene) { *actualFace = -1; return QPoint(); } // Get the combined matrix for the projection. int dpiX = widget->logicalDpiX(); int dpiY = widget->logicalDpiY(); QRectF bounds = boundingRect(); qreal aspectRatio = (bounds.width() * dpiY) / (bounds.height() * dpiX); QMatrix4x4 mv = camera()->modelViewMatrix(); QMatrix4x4 proj = camera()->projectionMatrix(aspectRatio); QMatrix4x4 combined = proj * mv; // Find the relative position of the point within (-1, -1) to (1, 1). QPointF relativePoint = QPointF((point.x() - bounds.center().x()) * 2 / bounds.width(), -(point.y() - bounds.center().y()) * 2 / bounds.height()); // Determine which face of the cube contains the point. QVector3D pt1, pt2, pt3, pt4; bool singleFace = (pressedFace != -1); for (int face = 0; face < 6; ++face) { if (singleFace && face != pressedFace) continue; // Create a polygon from the projected version of the face // so that we can test for point membership. pt1 = QVector3D(vertexData[face * 4 * 3], vertexData[face * 4 * 3 + 1], vertexData[face * 4 * 3 + 2]); pt2 = QVector3D(vertexData[face * 4 * 3 + 3], vertexData[face * 4 * 3 + 4], vertexData[face * 4 * 3 + 5]); pt3 = QVector3D(vertexData[face * 4 * 3 + 6], vertexData[face * 4 * 3 + 7], vertexData[face * 4 * 3 + 8]); pt4 = QVector3D(vertexData[face * 4 * 3 + 9], vertexData[face * 4 * 3 + 10], vertexData[face * 4 * 3 + 11]); QVector<QPointF> points2d; points2d.append((combined * pt1).toPointF()); points2d.append((combined * pt2).toPointF()); points2d.append((combined * pt3).toPointF()); points2d.append((combined * pt4).toPointF()); QPolygonF polygon(points2d); if (!singleFace) { if (!polygon.containsPoint(relativePoint, Qt::OddEvenFill)) continue; } // We want the face that is pointing towards the user. QVector3D v = mv.mapVector (QVector3D::crossProduct(pt2 - pt1, pt3 - pt1)); if (!singleFace && v.z() <= 0.0f) continue; // Determine the intersection between the cube face and // the ray coming from the eye position. QVector3D eyept = proj.inverted().map (QVector3D(relativePoint.x(), relativePoint.y(), -1.0f)); QLine3D ray(QVector3D(0, 0, 0), eyept); QPlane3D plane(mv * pt1, v); QResult<QVector3D> intersection = plane.intersection(ray); if (!intersection.isValid()) continue; QVector3D worldpt = mv.inverted().map(intersection.value()); // Map the world point to the range 0..1. worldpt = (worldpt / CubeSize) + QVector3D(0.5f, 0.5f, 0.5f); // Figure out the texture co-ordinates on the face that // correspond to the point. qreal xtex, ytex; switch (face) { case 0: xtex = 1.0f - worldpt.y(); ytex = 1.0f - worldpt.z(); break; case 1: xtex = 1.0f - worldpt.x(); ytex = 1.0f - worldpt.z(); break; case 2: xtex = worldpt.y(); ytex = 1.0f - worldpt.z(); break; case 3: xtex = worldpt.x(); ytex = 1.0f - worldpt.z(); break; case 4: xtex = worldpt.x(); ytex = 1.0f - worldpt.y(); break; case 5: default: xtex = worldpt.x(); ytex = worldpt.y(); break; } // Turn the texture co-ordinates into scene co-ordinates. bounds = mScene->sceneRect(); xtex *= bounds.width(); ytex *= bounds.height(); int x = qRound(xtex); int y = qRound(ytex); if (x < 0) x = 0; else if (x >= bounds.width()) x = qRound(bounds.width() - 1); if (y < 0) y = 0; else if (y >= bounds.height()) y = qRound(bounds.height() - 1); *actualFace = face; return QPoint(x, y); } *actualFace = -1; return QPoint(); }
void SelectionPointer::renderSelectionPointer(GLuint defaultFboHandle, bool useOrtho) { Q_UNUSED(defaultFboHandle) glViewport(m_mainViewPort.x(), m_mainViewPort.y(), m_mainViewPort.width(), m_mainViewPort.height()); Q3DCamera *camera = m_cachedScene->activeCamera(); QMatrix4x4 itModelMatrix; // Get view matrix QMatrix4x4 viewMatrix; QMatrix4x4 projectionMatrix; GLfloat viewPortRatio = (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height(); if (m_cachedIsSlicingActivated) { GLfloat sliceUnitsScaled = sliceUnits / m_autoScaleAdjustment; viewMatrix.lookAt(QVector3D(0.0f, 0.0f, 1.0f), zeroVector, upVector); projectionMatrix.ortho(-sliceUnitsScaled * viewPortRatio, sliceUnitsScaled * viewPortRatio, -sliceUnitsScaled, sliceUnitsScaled, -1.0f, 4.0f); } else if (useOrtho) { viewMatrix = camera->d_ptr->viewMatrix(); GLfloat orthoRatio = 2.0f; projectionMatrix.ortho(-viewPortRatio * orthoRatio, viewPortRatio * orthoRatio, -orthoRatio, orthoRatio, 0.0f, 100.0f); } else { viewMatrix = camera->d_ptr->viewMatrix(); projectionMatrix.perspective(45.0f, viewPortRatio, 0.1f, 100.0f); } QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; // Position the pointer ball modelMatrix.translate(m_position); if (!m_rotation.isIdentity()) { modelMatrix.rotate(m_rotation); itModelMatrix.rotate(m_rotation); } // Scale the point with fixed values (at this point) QVector3D scaleVector(0.05f, 0.05f, 0.05f); modelMatrix.scale(scaleVector); itModelMatrix.scale(scaleVector); MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; QVector3D lightPos = m_cachedScene->activeLight()->position(); // // Draw the point // m_pointShader->bind(); m_pointShader->setUniformValue(m_pointShader->lightP(), lightPos); m_pointShader->setUniformValue(m_pointShader->view(), viewMatrix); m_pointShader->setUniformValue(m_pointShader->model(), modelMatrix); m_pointShader->setUniformValue(m_pointShader->nModel(), itModelMatrix.inverted().transposed()); m_pointShader->setUniformValue(m_pointShader->color(), m_highlightColor); m_pointShader->setUniformValue(m_pointShader->MVP(), MVPMatrix); m_pointShader->setUniformValue(m_pointShader->ambientS(), m_cachedTheme->ambientLightStrength()); m_pointShader->setUniformValue(m_pointShader->lightS(), m_cachedTheme->lightStrength() * 2.0f); m_pointShader->setUniformValue(m_pointShader->lightColor(), Utils::vectorFromColor(m_cachedTheme->lightColor())); m_drawer->drawObject(m_pointShader, m_pointObj); }
void Scene::paintGL(){ setStates(); // включаем буфер глубины, свет и прочее (возможно можно вынести в initGL) //glClear(GL_COLOR_BUFFER_BIT); // если включен буфер глубины, то без его очистки мы ничего не увидим glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glMatrixMode(GL_PROJECTION); //qgluPerspective(60.0, width / height, 0.01, 15.0); //glMatrixMode(GL_MODELVIEW); //пишем матрицы преобразований QMatrix4x4 LMM; // Local Model matrix (делает преобразования в локальных координатах объекта, для одного объекта их может быть несколько для разных частей объекта) QMatrix4x4 MM; // Model matrix (выносит координаты объекта в координаты пространства сцены, //выполняется в следующем порядке - масштабирование, поворот, перенос) // TranslationMatrix * RotationMatrix * ScaleMatrix * OriginalVector; (в коде это выглядит в обратном порядке) QMatrix4x4 MVM; // ModelView matrix (View matrix)("масштабирует крутит и перемещает весь мир") QMatrix4x4 CameraView; // тоже самое что и MVM, но для использования функции LookAt QMatrix4x4 PM; // Projection matrix // проекционная матрица QMatrix4x4 MVPM; // ModelViewProjection matrix (projection * view * model) if (perspective) { // устанавливаем трёхмерную канву (в перспективной проекции) для рисования (плоскости отсечения) // угол перспективы, отношение сторон, расстояние до ближней отсекающей плоскости и дальней PM.perspective(cameraFocusAngle,ratio,0.1f,100.0f); // glFrustum( xmin, xmax, ymin, ymax, near, far) // gluPerspective(fovy, aspect, near, far) } else { // устанавливаем трёхмерную канву (в ортогональной проекции) для рисования (плоскости отсечения) PM.ortho(-2.0f,2.0f,-2.0f,2.0f,-8.0f,8.0f); // glOrtho(left,right,bottom,top,near,far) // увеличение значений уменьшает фигуры на сцене (по Z задаём больше, чтобы не видеть отсечение фигур) // переносим по z дальше, обязательное условие для перспективной проекции // по оси z 0 это "глаз", - движение камеры назад, + вперёд. } ///MVM.translate(0.0f,0.0f,-6.0f); // переносим по z от "глаз", сдвигаем камеру на минус, т.е. в сторону затылка. // не работает в ортогональной проекции если перенести слишком далеко, за пределы куба отсечения // оппа, мы видим передние границы пирамиды отсечения, где всё отсекается (тут-то шейдерным сферам и конец) // изменяем масштаб фигуры (увеличиваем) ///MVM.scale(10.0f); // отрицательное число переворачивает проекцию // влияет только на ортогональную проекцию // убивает Шферы // указываем угол поворота и ось поворота смотрящую из центра координат к точке x,y,z, MVM.rotate(m_angle,0.0f,1.0f,0.0f); // поворот вокруг оси центра координат CameraView.lookAt(cameraEye,cameraCenter,cameraUp); // установка камеры (матрицы трансфрмации) MVM=CameraView*MVM; // получаем матрицу трансформации итогового вида // находим проекционную инверсную мтрицу bool inverted; QMatrix4x4 PMi=PM.inverted(&inverted); if (!inverted) qDebug() << "PMi не конвертится"; MVPM=PM*MVM; QMatrix4x4 MVPMi=MVPM.inverted(&inverted); if (!inverted) qDebug() << "MVPMi не конвертится"; // РИСУЕМ ТРЕУГОЛЬНИК // инициализируем данные программы матрицы и атрибуты m_triangle->init(); // зaпихиваем в его программу матрицу ориентации m_triangle->m_program.setUniformValue(m_triangle->m_matrixUniform, MVPM); // вызываем функцию рисования объекта (или объектов в for) m_triangle->draw(); // проводим сброс инициализации параметров m_triangle->drop();//*/ //РИСУЕМ СФЕРЫ m_shphere->init(); m_shphere->m_program->setUniformValue(m_shphere->m_matrixUniform, MVPM); m_shphere->m_program->setUniformValue("PMi", PMi); m_shphere->m_program->setUniformValue("MVM", MVM); m_shphere->m_program->setUniformValue("MVPMi", MVPMi); m_shphere->m_program->setUniformValue("viewport",viewport); m_shphere->draw(); m_shphere->drop();//*/ }
void FiberRenderer::draw( QMatrix4x4 p_matrix, QMatrix4x4 mv_matrix, int width, int height, int renderMode, PropertyGroup* props ) { float alpha = props->get( Fn::Property::ALPHA ).toFloat(); if ( renderMode != 1 ) // we are not picking { if ( renderMode == 4 || renderMode == 5 ) // we are drawing opaque objects { if ( alpha < 1.0 ) { // obviously not opaque return; } } else // we are drawing tranparent objects { if ( !(alpha < 1.0 ) ) { // not transparent return; } } } QGLShaderProgram* program = GLFunctions::getShader( "fiber" ); program->bind(); GLFunctions::setupTextures(); GLFunctions::setTextureUniforms( GLFunctions::getShader( "fiber" ) ); // Set modelview-projection matrix program->setUniformValue( "mvp_matrix", p_matrix * mv_matrix ); program->setUniformValue( "mv_matrixInvert", mv_matrix.inverted() ); initGeometry(); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIds[ 0 ] ); glBindBuffer( GL_ARRAY_BUFFER, vboIds[ 1 ] ); setShaderVars( props ); program->setUniformValue( "u_alpha", alpha ); program->setUniformValue( "u_renderMode", renderMode ); program->setUniformValue( "u_canvasSize", width, height ); program->setUniformValue( "D0", 9 ); program->setUniformValue( "D1", 10 ); program->setUniformValue( "D2", 11 ); glLineWidth( props->get( Fn::Property::FIBER_THICKNESS ).toFloat() ); QVector<bool>*selected = m_selector->getSelection(); if ( props->get( Fn::Property::COLORMODE ).toInt() != 2 ) { for ( int i = 0; i < m_data.size(); ++i ) { if ( selected->at( i ) ) { glDrawArrays( GL_LINE_STRIP, m_startIndexes[i], m_pointsPerLine[i] ); } } } else { for ( int i = 0; i < m_data.size(); ++i ) { if ( selected->at( i ) ) { program->setUniformValue( "u_color", m_colorField[i].redF(), m_colorField[i].greenF(), m_colorField[i].blueF(), 1.0 ); glDrawArrays( GL_LINE_STRIP, m_startIndexes[i], m_pointsPerLine[i] ); } } } glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); }
void FiberRenderer::draw( QMatrix4x4 p_matrix, QMatrix4x4 mv_matrix, int width, int height, int renderMode, PropertyGroup& props ) { float alpha = props.get( Fn::Property::D_ALPHA ).toFloat(); if ( renderMode == 0 ) // picking { return; } else if ( renderMode == 1 ) // we are drawing opaque objects { if ( alpha < 1.0 ) { // obviously not opaque return; } } else // we are drawing tranparent objects { if ( !(alpha < 1.0 ) ) { // not transparent return; } } if ( m_updateExtraData ) { updateExtraData( m_selectedExtraData ); } QGLShaderProgram* program = GLFunctions::getShader( "fiber" ); program->bind(); GLFunctions::setupTextures(); GLFunctions::setTextureUniforms( GLFunctions::getShader( "fiber" ), "maingl" ); // Set modelview-projection matrix program->setUniformValue( "mvp_matrix", p_matrix * mv_matrix ); program->setUniformValue( "mv_matrixInvert", mv_matrix.inverted() ); program->setUniformValue( "mv_matrixTI", mv_matrix.transposed().inverted() ); program->setUniformValue( "userTransformMatrix", props.get( Fn::Property::D_TRANSFORM ).value<QMatrix4x4>() ); initGeometry(); glBindBuffer( GL_ARRAY_BUFFER, vbo ); setShaderVars( props ); glBindBuffer( GL_ARRAY_BUFFER, dataVbo ); int extraLocation = program->attributeLocation( "a_extra" ); program->enableAttributeArray( extraLocation ); glVertexAttribPointer( extraLocation, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0 ); glBindBuffer( GL_ARRAY_BUFFER, indexVbo ); int indexLocation = program->attributeLocation( "a_indexes" ); program->enableAttributeArray( indexLocation ); glVertexAttribPointer( indexLocation, 1, GL_FLOAT, GL_FALSE, sizeof(float), 0 ); program->setUniformValue( "u_alpha", alpha ); program->setUniformValue( "u_renderMode", renderMode ); program->setUniformValue( "u_canvasSize", width, height ); program->setUniformValue( "D0", 9 ); program->setUniformValue( "D1", 10 ); program->setUniformValue( "D2", 11 ); program->setUniformValue( "P0", 12 ); program->setUniformValue( "C5", 13 ); program->setUniformValue( "u_fibGrowth", props.get( Fn::Property::D_FIBER_GROW_LENGTH).toFloat() ); program->setUniformValue( "u_lighting", props.get( Fn::Property::D_LIGHT_SWITCH ).toBool() ); program->setUniformValue( "u_lightAmbient", props.get( Fn::Property::D_LIGHT_AMBIENT ).toFloat() ); program->setUniformValue( "u_lightDiffuse", props.get( Fn::Property::D_LIGHT_DIFFUSE ).toFloat() ); program->setUniformValue( "u_materialAmbient", props.get( Fn::Property::D_MATERIAL_AMBIENT ).toFloat() ); program->setUniformValue( "u_materialDiffuse", props.get( Fn::Property::D_MATERIAL_DIFFUSE ).toFloat() ); program->setUniformValue( "u_materialSpecular", props.get( Fn::Property::D_MATERIAL_SPECULAR ).toFloat() ); program->setUniformValue( "u_materialShininess", props.get( Fn::Property::D_MATERIAL_SHININESS ).toFloat() ); glLineWidth( props.get( Fn::Property::D_FIBER_THICKNESS ).toFloat() ); std::vector<bool>*selected = m_selector->getSelection(); int percent = props.get( Fn::Property::D_FIBER_THIN_OUT ).toFloat() * 10; for ( unsigned int i = 0; i < m_fibs->size(); ++i ) { if ( ( i % 1000 ) > percent ) { continue; } if ( selected->at( i ) ) { QColor c = m_fibs->at( i ).customColor(); program->setUniformValue( "u_color", c.redF(), c.greenF(), c.blueF(), 1.0 ); c = m_fibs->at( i ).globalColor(); program->setUniformValue( "u_globalColor", c.redF(), c.greenF(), c.blueF(), 1.0 ); glDrawArrays( GL_LINE_STRIP, m_startIndexes[i], m_pointsPerLine[i] ); } else { if ( Models::getGlobal( Fn::Property::G_UNSELECTED_FIBERS_GREY ).toBool() ) { program->setUniformValue( "u_color", .4f, .4f, .4f, 1.0 ); program->setUniformValue( "u_globalColor", .4f, .4f, .4f, 1.0 ); glDrawArrays( GL_LINE_STRIP, m_startIndexes[i], m_pointsPerLine[i] ); } } } glBindBuffer( GL_ARRAY_BUFFER, 0 ); }
/** \brief When a station has been selected, this updates the shot lines This shows the shot lines from the selected station. If no station is currently selected, this will hide the lines */ void cwScrapStationView::updateShotLines() { if(scrap() == nullptr) { return; } if(scrap()->parentNote() == nullptr) { return; } if(scrap()->parentNote()->parentTrip() == nullptr) { return; } if(transformUpdater() == nullptr) { return; } cwNoteStation noteStation = scrap()->station(selectedItemIndex()); //Get the current trip cwNote* note = scrap()->parentNote(); cwTrip* trip = note->parentTrip(); cwCave* cave = trip->parentCave(); cwStationPositionLookup stationPositionLookup = cave->stationPositionLookup(); //Clear all the lines ShotLines.clear(); if(noteStation.isValid() && stationPositionLookup.hasPosition(noteStation.name())) { QString stationName = noteStation.name(); QSet<cwStation> neighboringStations = trip->neighboringStations(stationName); //The position of the selected station QVector3D selectedStationPos = stationPositionLookup.position(noteStation.name()); //Create the matrix to covert global position into note position QMatrix4x4 noteTransformMatrix = scrap()->noteTransformation()->matrix(); //Matrix from page coordinates to cave coordinates noteTransformMatrix = noteTransformMatrix.inverted(); //From cave coordinates to page coordinates QMatrix4x4 notePageAspect = note->scaleMatrix().inverted(); //The note's aspect ratio QMatrix4x4 offsetMatrix; offsetMatrix.translate(-selectedStationPos); QMatrix4x4 dotPerMeter; dotPerMeter.scale(note->dotPerMeter(), note->dotPerMeter(), 1.0); QMatrix4x4 noteStationOffset; noteStationOffset.translate(QVector3D(noteStation.positionOnNote())); QMatrix4x4 toNormalizedNote = noteStationOffset * dotPerMeter * notePageAspect * noteTransformMatrix * offsetMatrix; //Only used if the scrap is in running profile QMatrix4x4 profileDirection = runningProfileDirection(); //Go through all the neighboring stations and add the position to the line foreach(cwStation station, neighboringStations) { QVector3D currentPos = stationPositionLookup.position(station.name()); if(scrap()->type() == cwScrap::RunningProfile) { bool foundStation = false; foreach(cwNoteStation currentNoteStation, scrap()->stations()) { if(currentNoteStation.name().toLower() == station.name().toLower()) { foundStation = true; } } if(foundStation) { continue; } //Caluclate the running profile rotation based on the stations QMatrix4x4 toProfileRotation = cwScrap::toProfileRotation(selectedStationPos, currentPos); toNormalizedNote = noteStationOffset * dotPerMeter * notePageAspect * noteTransformMatrix * profileDirection * toProfileRotation * offsetMatrix; }
void ARCameraCalibrator::drawCalibrationGrid() { using namespace QScrollEngine; QMutexLocker ml(&m_mutex); if (scene() == nullptr) return; if (m_lastCalibrationFrame->isCreated()) { QScrollEngineContext* context = scene()->parentContext(); AR::Point2i frameSize = m_lastCalibrationFrame->imageSize(); context->glDepthMask(GL_FALSE); context->glDisable(GL_DEPTH_TEST); context->glDisable(GL_BLEND); if (m_flagUpdateFrameTexture) { if (m_tempFrameTexture->isCreated()) { if ((m_tempFrameTexture->width() != m_lastImage.width()) || (m_tempFrameTexture->height() != m_lastImage.height())) { m_tempFrameTexture->bind(); m_tempFrameTexture->destroy(); m_tempFrameTexture->setFormat(QOpenGLTexture::RGBA8_UNorm); m_tempFrameTexture->setSize(m_lastImage.width(), m_lastImage.height(), 4); m_tempFrameTexture->allocateStorage(); } else { m_tempFrameTexture->bind(); } } else { m_tempFrameTexture->create(); m_tempFrameTexture->bind(); m_tempFrameTexture->setFormat(QOpenGLTexture::RGBA8_UNorm); m_tempFrameTexture->setSize(m_lastImage.width(), m_lastImage.height(), 4); m_tempFrameTexture->allocateStorage(); } if (m_lastPixelFormat == QVideoFrame::Format_BGR32) { m_tempFrameTexture->setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, m_lastImage.data()); } else { m_tempFrameTexture->setData(QOpenGLTexture::BGRA, QOpenGLTexture::UInt8, m_lastImage.data()); } m_tempFrameTexture->generateMipMaps(); } m_textureRenderer->draw(m_tempFrameTexture->textureId(), m_textureMatrix); QMatrix4x4 textureMatrix; textureMatrix.fill(0.0f); for (int i=0; i<2; ++i) { textureMatrix(i, 0) = m_textureMatrix(i, 0); textureMatrix(i, 1) = m_textureMatrix(i, 1); textureMatrix(i, 3) = m_textureMatrix(i, 2); } textureMatrix(3, 0) = m_textureMatrix(2, 0); textureMatrix(3, 1) = m_textureMatrix(2, 1); textureMatrix(3, 3) = m_textureMatrix(2, 2); QMatrix4x4 t; t.setToIdentity(); t(0, 0) = 0.5f; t(1, 1) = -0.5f; t(0, 3) = 0.5f; t(1, 3) = 0.5f; QMatrix4x4 transformMatrix; transformMatrix.ortho(0.0f, (float)(frameSize.x), 0.0f, (float)(frameSize.y), 0.0f, 1.0f); transformMatrix = t.inverted() * textureMatrix * t * transformMatrix; int countLineVertices; QVector2D* lineVertices; context->glLineWidth(4.0f); countLineVertices = (int)(m_linesOfImageGrid.size() * 2); lineVertices = new QVector2D[countLineVertices]; for (int i=0; i<(int)m_linesOfImageGrid.size(); ++i) { std::pair<AR::Point2f, AR::Point2f>& line = m_linesOfImageGrid[i]; lineVertices[i * 2].setX(line.first.x); lineVertices[i * 2].setY(line.first.y); lineVertices[i * 2 + 1].setX(line.second.x); lineVertices[i * 2 + 1].setY(line.second.y); } context->drawLines(lineVertices, countLineVertices, QColor(0, 155, 255), transformMatrix); delete[] lineVertices; context->glEnable(GL_BLEND); /*countLineVertices = (int)(m_linesOf3DGrid.size() * 2); lineVertices = new QVector2D[countLineVertices]; for (int i=0; i<(int)m_linesOf3DGrid.size(); ++i) { std::pair<AR::Point2f, AR::Point2f>& line = m_linesOf3DGrid[i]; lineVertices[i * 2].setX(line.first.x); lineVertices[i * 2].setY(line.first.y); lineVertices[i * 2 + 1].setX(line.second.x); lineVertices[i * 2 + 1].setY(line.second.y); } context->drawLines(lineVertices, countLineVertices, QColor(155, 0, 255, 100), transformMatrix); delete[] lineVertices;*/ context->glLineWidth(4.0f); countLineVertices = (int)(m_errors.size() * 2); lineVertices = new QVector2D[countLineVertices]; for (int i=0; i<(int)m_errors.size(); ++i) { std::pair<AR::Point2f, AR::Point2f>& line = m_errors[i]; lineVertices[i * 2].setX(line.first.x); lineVertices[i * 2].setY(line.first.y); lineVertices[i * 2 + 1].setX(line.second.x); lineVertices[i * 2 + 1].setY(line.second.y); } context->drawLines(lineVertices, countLineVertices, QColor(255, 255, 0, 200), transformMatrix); delete[] lineVertices; context->glDisable(GL_BLEND); } }
void HeightMap3DRenderer::render(){ if(!m_initialized)initialize(); QMatrix4x4 modelMatrix; modelMatrix.rotate(-90, {1,0,0}); const float rootSize = 50; modelMatrix.scale(rootSize); //select terrain patches of different lod levels here //TODO maybe this is not the right place for this kind of code... std::vector<float> ranges; { ranges.push_back(0.125); float lowestLodRes = rootSize; while(lowestLodRes > 0.25){ ranges.push_back(ranges.back()*2); lowestLodRes /= 2; } } std::vector<TerrainPatchSelection> selections; const int lodLevelCount = ranges.size()+1; const float rootScale = rootSize; TerrainPatchSelection rootQuad{lodLevelCount-1,{0,0,0},rootScale}; QVector3D observerPosition = modelMatrix.inverted() * m_state.camera.position(); observerPosition.setZ(0);//TODO don't ignore height rootQuad.lodSelect(ranges,observerPosition,selections); glClearColor(0.6, 0.85, 1, 1); glDepthMask(GL_TRUE); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); if(!m_program || m_sourceDirty){ recompileProgram(); } m_program->bind(); m_program->enableAttributeArray(0); //set gl states for terrain rendering //TODO maybe some of these are remembered by vao? glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); glDisable(GL_BLEND); glCullFace(GL_BACK); QMatrix4x4 viewMatrix = m_state.camera.worldToLocalMatrix(); QMatrix4x4 projectionMatrix; projectionMatrix.perspective(65, m_aspectRatio, 1.0, 10024); // projectionMatrix.ortho(-10,10,-10,10,0.10,10); projectionMatrix.scale({1,-1,1}); //flip Y coordinates because otherwise Qt will render it upside down QMatrix4x4 modelViewMatrix = viewMatrix * modelMatrix; QMatrix4x4 mvp = projectionMatrix * modelViewMatrix; //uniforms shared between patches m_program->setUniformValue("modelViewMatrix", modelViewMatrix); m_program->setUniformValue("normalMatrix", modelViewMatrix.normalMatrix()); m_program->setUniformValue("projectionMatrix", projectionMatrix); m_program->setUniformValue("mvp", mvp); m_program->setUniformValue("sampleOffset", QVector2D(m_state.center.x(), m_state.center.y())); m_program->setUniformValue("scaling", QVector3D( 1.0/m_state.widthScale * 0.1, //TODO get rid of these magic constants 1.0/m_state.widthScale * 0.1, m_state.heightScale //height scaling ) ); //this is where the magic happens { QOpenGLVertexArrayObject::Binder binder(&m_vao); //loop through all selected terrain patches for (TerrainPatchSelection selection : selections) { QVector2D patchOffset{selection.position.x(), selection.position.y()}; m_program->setUniformValue("patchOffset", patchOffset); m_program->setUniformValue("patchSize", selection.size); glDrawArrays(GL_TRIANGLE_STRIP, 0, m_vertexCount); } } m_program->release(); }
// ドロップ時のスロット // レイヤ追加 void AnimationForm::slot_dropedImage( QRectF rect, QPoint pos, int imageIndex ) { CObjectModel *pModel = m_pEditData->getObjectModel() ; int frameNum = ui->label_frame->value() ; QModelIndex index = ui->treeView->currentIndex() ; if ( !index.isValid() ) { qWarning() << "slot_dropedImage current index invalid 0" ; return ; } ObjectItem *pObjItem = pModel->getObject(index) ; if ( !pObjItem ) { qWarning() << "slot_dropedImage current obj 0" ; return ; } if ( !m_pSetting->getLayerHierarchy() ) { index = pObjItem->getIndex() ; } pos -= QPoint((m_pSetting->getAnmWindowW()/2), (m_pSetting->getAnmWindowH()/2)) ; // GLWidgetのローカルポスに変換 ObjectItem *pItem = pModel->getItemFromIndex(index) ; bool valid ; QMatrix4x4 mat = pItem->getDisplayMatrix(frameNum, &valid) ; if ( valid ) { QMatrix4x4 inv = mat.inverted(&valid) ; if ( valid ) { pos = inv.map(pos) ; } } index = m_pEditData->cmd_addItem(QString("Layer %1").arg(pObjItem->childCount()), index) ; ui->treeView->setCurrentIndex(index) ; // m_pEditData->setSelIndex(index) ; // ツリービューに追加 FrameData frameData ; frameData.pos_x = pos.x() ; frameData.pos_y = pos.y() ; frameData.pos_z = 0 ; frameData.rot_x = frameData.rot_y = frameData.rot_z = 0 ; frameData.center_x = (rect.width()) / 2 ; frameData.center_y = (rect.height()) / 2 ; frameData.frame = frameNum ; frameData.fScaleX = frameData.fScaleY = 1.0f ; frameData.setRect(rect); frameData.nImage = imageIndex ; frameData.bUVAnime = false ; frameData.rgba[0] = frameData.rgba[1] = frameData.rgba[2] = frameData.rgba[3] = 255 ; QList<QWidget *> updateWidget ; updateWidget << m_pGlWidget ; updateWidget << m_pDataMarker ; m_pEditData->cmd_addFrameData(index, frameData, updateWidget) ; }
void GLViewer::setViewPoint(QMatrix4x4 new_vp){ ///Moving the camera is inverse to moving the points to draw viewpoint_tf_ = new_vp.inverted(); }
void set_transform(QMatrix4x4 m) { m_trans = m; m_invtrans = m.inverted(); }
void DrawContext::ActivateMaterial() { program_->bind(); glFrontFace(GL_CCW); // set OpenGL attributes based on material properties. const bool mat_two_sided = material_->TwoSided(); if (mat_two_sided != gl_two_sided_) { gl_two_sided_ = mat_two_sided; if (gl_two_sided_) { glDisable(GL_CULL_FACE); } else { glCullFace(GL_BACK); glEnable(GL_CULL_FACE); } } const bool mat_depth_test = material_->DepthTest(); if (mat_depth_test != gl_depth_test_) { gl_depth_test_ = mat_depth_test; if (gl_depth_test_) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } } const GLenum mat_depth_func = material_->DepthFunc(); if (mat_depth_func != gl_depth_func_) { gl_depth_func_ = mat_depth_func; glDepthFunc(gl_depth_func_); } const bool mat_depth_write = material_->DepthWrite(); if (gl_depth_write_ != mat_depth_write) { gl_depth_write_ = mat_depth_write; if (gl_depth_write_) { glDepthMask(GL_TRUE); } else { glDepthMask(GL_FALSE); } } const bool mat_color_write = material_->ColorWrite(); if (gl_color_write_ != mat_color_write) { gl_color_write_ = mat_color_write; if (gl_color_write_) { glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } else { glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); } } const float mat_point_size = material_->PointSize(); if (gl_point_size_ != mat_point_size) { gl_point_size_ = mat_point_size; glPointSize(gl_point_size_); } const float mat_line_width = material_->LineWidth(); if (gl_line_width_ != mat_line_width) { gl_line_width_ = mat_line_width; glLineWidth(gl_line_width_); } const bool mat_blend = material_->Blend(); if (gl_blend_ != mat_blend) { gl_blend_ = mat_blend; if (gl_blend_) { glEnable(GL_BLEND); } else { glDisable(GL_BLEND); } } GLenum mat_sfactor; GLenum mat_dfactor; material_->BlendFunc(&mat_sfactor, &mat_dfactor); if (gl_sfactor_ != mat_sfactor || gl_dfactor_ != mat_dfactor) { gl_sfactor_ = mat_sfactor; gl_dfactor_ = mat_dfactor; glBlendFunc(gl_sfactor_, gl_dfactor_); } // Set shader standard variables const ShaderStandardVariables& locs = shader_->StandardVariables(); const QMatrix4x4 proj_mat = cur_camera_->GetProjectionMatrix(); const QMatrix4x4 view_mat = cur_camera_->GetViewMatrix(); // Set uniform variables if (locs.sv_proj_mat >= 0) { program_->setUniformValue(locs.sv_proj_mat, proj_mat); } if (locs.sv_view_mat >= 0) { program_->setUniformValue(locs.sv_view_mat, view_mat); } if (locs.sv_view_mat_inv >= 0) { program_->setUniformValue(locs.sv_view_mat_inv, view_mat.inverted()); } if (locs.sv_model_mat >= 0) { program_->setUniformValue(locs.sv_model_mat, model_mat_); } if (locs.sv_mvp_mat >= 0) { program_->setUniformValue(locs.sv_mvp_mat, proj_mat * view_mat * model_mat_); } if (locs.sv_mv_mat >= 0) { program_->setUniformValue(locs.sv_mv_mat, view_mat * model_mat_); } if (locs.sv_model_normal_mat >= 0) { program_->setUniformValue(locs.sv_model_normal_mat, model_mat_.normalMatrix()); } const std::vector<LightNode*>& lights = scene_->Lights(); int num_lights = lights.size(); if (num_lights > kShaderMaxLights) { printf("Too many lights. Max: %d\n", kShaderMaxLights); num_lights = kShaderMaxLights; } for (int light_ind = 0; light_ind < num_lights; ++light_ind) { const LightNode* light_node = lights[light_ind]; const ShaderLightLocation light_loc = locs.sv_lights[light_ind]; LightType light_type = light_node->GetLightType(); if (light_loc.is_directional >= 0) { const bool is_directional = light_type == LightType::kDirectional; program_->setUniformValue(light_loc.is_directional, is_directional); } if (light_loc.direction >= 0) { const QVector3D light_dir = light_node->Direction(); program_->setUniformValue(light_loc.direction, light_dir); } if (light_loc.position >= 0) { const QVector3D light_pos = light_node->Translation(); program_->setUniformValue(light_loc.position, light_pos); } if (light_loc.ambient >= 0) { const float ambient = light_node->Ambient(); program_->setUniformValue(light_loc.ambient, ambient); } if (light_loc.specular >= 0) { const float specular = light_node->Specular(); program_->setUniformValue(light_loc.specular, specular); } if (light_loc.color >= 0) { const QVector3D color = light_node->Color(); program_->setUniformValue(light_loc.color, color); } if (light_loc.attenuation >= 0) { const float attenuation = light_node->Attenuation(); program_->setUniformValue(light_loc.attenuation, attenuation); } if (light_loc.cone_angle >= 0) { const float cone_angle = light_node->ConeAngle() * M_PI / 180; program_->setUniformValue(light_loc.cone_angle, cone_angle); } } // Load shader uniform variables from the material for (auto& item : material_->ShaderParameters()) { ShaderUniform& uniform = item.second; uniform.LoadToProgram(program_); } // Load textures unsigned int texunit = 0; for (auto& item : material_->GetTextures()) { const QString& texname = item.first; const std::shared_ptr<QOpenGLTexture>& texture = item.second; texture->bind(texunit); program_->setUniformValue(texname.toStdString().c_str(), texunit); } }
void set_transform(const QMatrix4x4& m) { m_trans = m; m_invtrans = m.inverted(); }
#include <fugio/context_interface.h> MatrixInverseNode::MatrixInverseNode( QSharedPointer<fugio::NodeInterface> pNode ) : NodeControlBase( pNode ) { FUGID( PIN_INPUT_MATRIX, "9e154e12-bcd8-4ead-95b1-5a59833bcf4e" ); FUGID( PIN_OUTPUT_MATRIX, "1b5e9ce8-acb9-478d-b84b-9288ab3c42f5" ); mPinMatrixInput = pinInput( "Matrix", PIN_INPUT_MATRIX ); mPinMatrixInput->registerPinInputType( PID_MATRIX4 ); mValMatrixOutput = pinOutput<fugio::VariantInterface *>( "Matrix", mPinMatrixOutput, PID_MATRIX4, PIN_OUTPUT_MATRIX ); } void MatrixInverseNode::inputsUpdated( qint64 pTimeStamp ) { Q_UNUSED( pTimeStamp ) bool IOK; QMatrix4x4 Mat = variant( mPinMatrixInput ).value<QMatrix4x4>(); QMatrix4x4 Inv = Mat.inverted( &IOK ); if( IOK && Inv != mValMatrixOutput->variant().value<QMatrix4x4>() ) { mValMatrixOutput->setVariant( Inv ); pinUpdated( mPinMatrixOutput ); } }