예제 #1
0
// Renders the requested list of faces
// Normal faces are rendered with vertex arrays and multitexturing. The first TMU handles the 
// lightmap, while the second TMU handles the surface texture itself.
int GLDriver::drawGeometryList(GeometryList* l)
{
	Assert(l != NULL);
	if(lastTime == 0)
		lastTime = timeGetTime();
	renderTime = timeGetTime();
	qmap = l->mapData;

	ShaderUtils::renderTime = renderTime;
	ShaderUtils::qmap = qmap;
	ShaderUtils::textureFactory = textureFactory;
	qsort(l->faces, l->faceCount, sizeof(int), TransSort);

	glActiveTextureARB(GL_TEXTURE1_ARB);
	glDisable(GL_TEXTURE_2D);

	glClientActiveTextureARB(GL_TEXTURE1_ARB);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	glActiveTextureARB(GL_TEXTURE0_ARB);
	glEnable(GL_TEXTURE_2D);
	glClientActiveTextureARB(GL_TEXTURE0_ARB);

	glDepthFunc(GL_LEQUAL);

	float timeDiff = renderTime - lastTime;
    drawSky(l, timeDiff);
    drawFaces(l, timeDiff);
    drawMeshes(l, timeDiff);
    drawPatches(l);
    //drawFog(l);

	lastTime = renderTime;
	return 0;
}
예제 #2
0
/*!
Draws the the nodes meshes with SLNode::drawMeshes and calls 
recursively the drawRec method of the nodes children. 
The nodes object matrix (SLNode::_om) is multiplied before the meshes are drawn. 
This recursive drawing is more expensive than the flat drawing with the 
opaqueNodes vector because of the additional matrix multiplications. 
The order of drawing doesn't matter in flat drawing because the world 
matrix (SLNode::_wm) is used for transform. See also SLNode::drawMeshes.
The drawRec method is <b>still used</b> for the rendering of the 2D menu!
*/
void SLNode::drawRec(SLSceneView* sv)
{   
    // Do frustum culling for all shapes except cameras & lights
    if (sv->doFrustumCulling() && !_aabb.isVisible()) return; 
   
    _stateGL->pushModelViewMatrix();
    _stateGL->modelViewMatrix.multiply(_om.m());
    _stateGL->buildInverseAndNormalMatrix();
   
    ///////////////
    drawMeshes(sv);
    ///////////////
   
    for (auto child : _children)
        child->drawRec(sv);

    _stateGL->popModelViewMatrix();

    // Draw axis aligned bounding box
    SLbool showBBOX = sv->drawBit(SL_DB_BBOX) || drawBit(SL_DB_BBOX);
    SLbool showAXIS = sv->drawBit(SL_DB_AXIS) || drawBit(SL_DB_AXIS);
    SLbool showSELECT = drawBit(SL_DB_SELECTED);
    if (showBBOX || showAXIS || showSELECT)
    {  
        _stateGL->pushModelViewMatrix();
        _stateGL->modelViewMatrix.setMatrix(sv->camera()->updateAndGetVM().m());
      
        // Draw AABB of all other shapes only
        if (showBBOX && !showSELECT)
        {   if (_meshes.size() > 0)
                 _aabb.drawWS(SLCol3f(1,0,0));
            else _aabb.drawWS(SLCol3f(1,0,1));
        }

        if (showAXIS)
            _aabb.drawAxisWS();

        // Draw AABB if shapes is selected
        if (showSELECT)
            _aabb.drawWS(SLCol3f(1,1,0));

        _stateGL->popModelViewMatrix(); 
    }
}
////////////////////////////////////////////////////////////////////////////////
// SoftShadowsRenderer::render()
////////////////////////////////////////////////////////////////////////////////
void SoftShadowsRenderer::render(float deltaTime)
{
    // Frame counter
    m_frameNumber++;
    
    // Bind all our textures and samplers
    for (GLuint unit = 0; unit < NumTextureUnits; ++unit)
    {
        glActiveTexture(GL_TEXTURE0 + unit);
        glBindTexture(GL_TEXTURE_2D, m_textures[unit]);
        glBindSampler(unit, m_samplers[unit]);
    }
    
    //
    // STEP 1: render shadow map from the light's point of view
    //
    if (m_shadowTechnique != None || m_visualizeDepthTexture)
    {
        GLuint prevFBO = 0;
        // Enum has MANY names based on extension/version
        // but they all map to 0x8CA6
        glGetIntegerv(0x8CA6, (GLint*)&prevFBO);

        glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFramebuffer);

        glViewport(0, 0, LIGHT_RES, LIGHT_RES);
        glClear(GL_DEPTH_BUFFER_BIT);

        glEnable(GL_POLYGON_OFFSET_FILL);
        glPolygonOffset(4.0f, 32.0f);

        m_shadowMapShader->enable();
        drawMeshes(*m_shadowMapShader);
        m_shadowMapShader->disable();

        glDisable(GL_POLYGON_OFFSET_FILL);
        glBindFramebuffer(GL_FRAMEBUFFER, prevFBO);
        glViewport(0, 0, m_screenWidth, m_screenHeight);
    }

    //
    // STEP 2: render scene from the eye's point of view
    //	
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    if (m_visualizeDepthTexture)
    {
        m_visTexShader->enable();

        glDisable(GL_DEPTH_TEST);
        glDisable(GL_CULL_FACE);

        NvDrawQuadGL(
            m_visTexShader->getPositionAttrHandle(),
            m_visTexShader->getTexCoordAttrHandle());

        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);

        m_visTexShader->disable();
    }
    else
    {
        // To reduce overdraw, do a depth prepass to layout z
        m_depthPrepassShader->enable();

        drawMeshes(*m_depthPrepassShader);
        drawGround(*m_depthPrepassShader);

        m_depthPrepassShader->disable();
        
        // Do the shading pass
        EyeShader *shader = 0;
        switch (m_shadowTechnique)
        {            
        case None:        
            shader = m_pcssShader;
            m_pcssShader->enable();
            m_pcssShader->setShadowTechnique(static_cast<GLint>(m_shadowTechnique));
            break;

        case PCSS:
            shader = m_pcssShader;
            m_pcssShader->enable();
            m_pcssShader->setShadowTechnique(static_cast<GLint>(m_shadowTechnique));
            m_pcssShader->setSamplePattern(static_cast<GLint>(m_pcssSamplePattern));
            break;

        case PCF:
            shader = m_pcssShader;
            m_pcssShader->enable();
            m_pcssShader->setShadowTechnique(static_cast<GLint>(m_shadowTechnique));
            m_pcssShader->setSamplePattern(static_cast<GLint>(m_pcfSamplePattern));
            break;
        }
        if (shader != 0)
        {
            glDepthFunc(GL_EQUAL);

            drawMeshes(*shader);
            drawGround(*shader);

            shader->disable();
            glDepthFunc(GL_LEQUAL);
        }
        CHECK_GL_ERROR();
    }

    for (GLuint unit = 0; unit < NumTextureUnits; ++unit)
    {
        glBindSampler(unit, 0);
    }
}
예제 #4
0
void View3D::paintGL()
{
    if (m_badOpenGL)
        return;
    QTime frameTimer;
    frameTimer.start();

    // Get window size
    double dPR = getDevicePixelRatio();
    int w = width() * dPR;
    int h = height() * dPR;

    // detecting a change in the device pixel ratio, since only the new QWindow (Qt5) would
    // provide a signal for screen changes and this is the easiest solution
    if (dPR != m_devicePixelRatio)
    {
        m_devicePixelRatio = dPR;
        resizeGL(w, h);
    }

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_incrementalFramebuffer);

    //--------------------------------------------------
    // Draw main scene
    TransformState transState(Imath::V2i(w, h),
                              m_camera.projectionMatrix(),
                              m_camera.viewMatrix());

    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glClearColor(m_backgroundColor.redF(), m_backgroundColor.greenF(),
                 m_backgroundColor.blueF(), 1.0f);
    if (!m_incrementalDraw)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    std::vector<const Geometry*> geoms = selectedGeometry();

    // Draw bounding boxes
    if(m_drawBoundingBoxes && !m_incrementalDraw)
    {
        if (m_boundingBoxShader->isValid())
        {
            QGLShaderProgram &boundingBoxShader = m_boundingBoxShader->shaderProgram();
            // shader
            boundingBoxShader.bind();
            // matrix stack
            transState.setUniforms(boundingBoxShader.programId());

            for (size_t i = 0; i < geoms.size(); ++i)
            {
                drawBoundingBox(transState, geoms[i]->getVAO("boundingbox"), geoms[i]->boundingBox().min,
                                Imath::C3f(1), geoms[i]->shaderId("boundingbox")); //boundingBoxShader.programId()
            }
        }
    }

    // Draw meshes and lines
    if (!m_incrementalDraw)
    {
        drawMeshes(transState, geoms);
        // Generic draw for any other geometry
        // (TODO: make all geometries use this interface, or something similar)
        // FIXME - Do generic quality scaling
        const double quality = 1;
        for (size_t i = 0; i < geoms.size(); ++i)
            geoms[i]->draw(transState, quality);
    }


    // Aim for 40ms frame time - an ok tradeoff for desktop usage
    const double targetMillisecs = 40;
    double quality = m_drawCostModel.quality(targetMillisecs, geoms, transState,
                                             m_incrementalDraw);

    // Render points
    DrawCount drawCount = drawPoints(transState, geoms, quality, m_incrementalDraw);

    // Measure frame time to update estimate for how much geometry we can draw
    // with a reasonable frame rate
    glFinish();
    int frameTime = frameTimer.elapsed();

    if (!geoms.empty())
        m_drawCostModel.addSample(drawCount, frameTime);


    // Debug: print bar showing how well we're sticking to the frame time
//    int barSize = 40;
//    std::string s = std::string(barSize*frameTime/targetMillisecs, '=');
//    if ((int)s.size() > barSize)
//        s[barSize] = '|';
//    tfm::printfln("%12f %4d %s", quality, frameTime, s);

    // TODO: this should really render a texture onto a quad and not use glBlitFramebuffer
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, m_incrementalFramebuffer);
    glBlitFramebuffer(0,0,w,h, 0,0,w,h,
                      GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); // has to be GL_NEAREST to work with DEPTH

    // Draw a grid for orientation purposes
    if (m_drawGrid)
        drawGrid();

    // Draw overlay stuff, including cursor position.
    if (m_drawCursor)
        drawCursor(transState, m_cursorPos, 10);
        //drawCursor(transState, m_camera.center(), 10);

    // Draw overlay axes
    if (m_drawAxes)
        drawAxes();

    // Set up timer to draw a high quality frame if necessary
    if (!drawCount.moreToDraw)
        m_incrementalFrameTimer->stop();
    else
        m_incrementalFrameTimer->start(10);

    m_incrementalDraw = true;

    glFrameBufferStatus(m_incrementalFramebuffer);
    glCheckError();
}
예제 #5
0
파일: Plant.cpp 프로젝트: ofZach/funkyForms
// ----------- draw
void Plant::draw(){
//    rig.draw();
//    drawPolylines();
    drawMeshes();
}