示例#1
0
static void page_create( Page* pPage, int width, int height )
{
    SYS_VERIFY( rendertarget_create( &pPage->bgTarget, width, height, PixelFormat_R8G8B8A8 ) );
    SYS_VERIFY( rendertarget_create( &pPage->fgTarget, width, height, PixelFormat_R8G8B8A8 ) );
    SYS_VERIFY( rendertarget_create( &pPage->burnTarget, width, height, PixelFormat_R8G8B8A8 ) );

    // render into render target:
    graphics_setRenderTarget( &pPage->bgTarget );   
    graphics_setBlendMode( BlendMode_Disabled );

    // render paper:
    graphics_setShader( &s_renderer.paperShader );    
    graphics_setFp4f( 0u, float_rand(), float_rand(), 2.0f / width, 2.0f / height );
    graphics_setVp4f( 0u, 32.0f, 18.0f, 0.4f, 0.3f );    
    graphics_setFsTexture(0,s_renderer.noiseTarget.id,SamplerState_MirrorU_MirrorV_Bilinear);
    graphics_drawFullscreenQuad();
   
    // clear fg+burn target:
    graphics_setShader( 0 );

    graphics_setRenderTarget( &pPage->fgTarget );
    graphics_clear( 0.0f, 0.0f, 0.0f, 0.0f );

    graphics_setRenderTarget( &pPage->burnTarget );
    graphics_clear( 0.0f, 0.0f, 0.0f, 0.0f );
}
示例#2
0
void renderer_drawCircle(const float2* pPos, float radius,const float3* pColor)
{
    Page* pPage = &s_renderer.pages[ s_renderer.currentPage ];
    graphics_setRenderTarget( &pPage->fgTarget );
    graphics_setShader( &s_renderer.debugPenShader );
    graphics_setBlendMode( BlendMode_Over );

    graphics_setFp4f( 0u, pColor->x, pColor->y, pColor->z, 1.0f );
    graphics_drawCircle(pPos,radius);
}
示例#3
0
文件: graphics.c 项目: ezhangle/motor
void graphics_reset(void) {
  // TODO point and line drawing modes
  matrixstack_origin();
  graphics_setColor(1.0f, 1.0f, 1.0f, 1.0f);
  graphics_setBackgroundColor(0.0f, 0.0f, 0.0f, 1.0f);
  graphics_setBlendMode(graphics_BlendMode_alpha);
  graphics_setDefaultShader();
  graphics_setColorMask(true, true, true, true);
  graphics_clearScissor();
  graphics_setCanvas(NULL);
}
示例#4
0
static void drawBurnHole( const BurnHole* pBurnHole )
{
    const float size=pBurnHole->size;
    if( size <= 0.0f )
    {
        return;
    }
    
    Page* pPage = &s_renderer.pages[ s_renderer.currentPage ];
    graphics_setRenderTarget( &pPage->burnTarget );
    graphics_setShader( &s_renderer.burnHoleShader );
    graphics_setBlendMode( BlendMode_Over );
    graphics_setFsTexture( 0, s_renderer.noiseTarget.id, SamplerState_MirrorU_MirrorV_Bilinear );

    const float initialSize=pBurnHole->initialSize;
    const float rot=pBurnHole->rot;
    const float2 start=pBurnHole->start;
    const float2 end=pBurnHole->end;

    const float len=float2_distance(&start,&end);
    const float s=initialSize;
    const float us=(len+2.0f*s)/10.0f;
    const float vs=2.0f*s/10.0f;
    
    graphics_setFp4f(0u,start.x,start.y,end.x,end.y);
    graphics_setFp4f(1u,size,0.0f,0.0f,0.0f);

    float2 dir;
    float2_normalize(float2_sub(&dir, &end, &start));

    float2 normal;
    float2_perpendicular(&normal, &dir);
    
    float2 v[4u];
    float2_addScaled1f(&v[0u], &start, &normal,  s);
    float2_addScaled1f(&v[1u], &start, &normal, -s);
    float2_addScaled1f(&v[2u], &end, &normal, -s);
    float2_addScaled1f(&v[3u], &end, &normal,  s);

    float2_addScaled1f(&v[0u], &v[0u], &dir, -s);
    float2_addScaled1f(&v[1u], &v[1u], &dir, -s);
    float2_addScaled1f(&v[2u], &v[2u], &dir, s);
    float2_addScaled1f(&v[3u], &v[3u], &dir, s);

    float2 uv0, uv1;
    float2_set(&uv0,0.0f,0.0f);
    float2_set(&uv1,us,vs);
    float2x2 rotM;
    float2x2_rotationY(&rotM,rot);
/*    float2x2_transform(&uv0,&rotM,&uv0);
    float2x2_transform(&uv1,&rotM,&uv1);*/
    graphics_drawQuad(v,uv0.x,uv0.y,uv1.x,uv1.y);
}
示例#5
0
void renderer_drawFrame( const FrameData* pFrame )
{
    SYS_USE_ARGUMENT( pFrame );

    // now render the final screen 
    graphics_setRenderTarget( 0 );

    graphics_setBlendMode( BlendMode_Disabled );

    // render paper:
    graphics_setShader( &s_renderer.pageShader );

    const Page* pCurrentPage=&s_renderer.pages[s_renderer.currentPage];
    graphics_setFsTexture(0,pCurrentPage->bgTarget.id,SamplerState_ClampU_ClampV_Nearest);
    graphics_setFsTexture(1,pCurrentPage->fgTarget.id,SamplerState_ClampU_ClampV_Nearest);
    graphics_setFsTexture(2,pCurrentPage->burnTarget.id,SamplerState_ClampU_ClampV_Nearest);
    
    graphics_drawFullscreenQuad();

    // render the flipped page on top:
    if( s_renderer.flipTime >= 0.0f )
    {
        const float flipProgress=float_saturate( s_renderer.flipTime / s_renderer.flipDuration );
        //SYS_TRACE_DEBUG( "%f (%f/%f)\n", flipProgress, s_renderer.flipTime, s_renderer.flipDuration );

        graphics_setShader( &s_renderer.pageFlipShader );

        const Page* pLastPage=&s_renderer.pages[s_renderer.lastPage];
        graphics_setFsTexture(0,pLastPage->bgTarget.id,SamplerState_ClampU_ClampV_Trilinear);
        graphics_setFsTexture(1,pLastPage->fgTarget.id,SamplerState_ClampU_ClampV_Trilinear);
        graphics_setFsTexture(2,pLastPage->burnTarget.id,SamplerState_ClampU_ClampV_Trilinear);

        float3 flipParams;
        computeFlipParams( &flipParams, flipProgress );
        graphics_setVp4f( 0u, flipParams.x, flipParams.y, flipParams.z, 0.0f );
        graphics_drawMesh2d( &s_renderer.pageFlipMesh ); 
    }
}
示例#6
0
void renderer_flipPage()
{
    // 
    if( s_renderer.flipTime >= 0.0f )
    {
        //SYS_TRACE_WARNING( "starting page flip while another flip is still active!\n" ); 
    }
    
    s_renderer.lastPage = s_renderer.currentPage;
    s_renderer.currentPage = 1 - s_renderer.currentPage;

    //s_renderer.currentStroke.pDefinition = 0;
    s_renderer.currentCommand = 0u;
    clearStrokeBuffer( &s_renderer.strokeBuffer );

    setPageState( PageState_BeforeDraw );

    Page* pPage = &s_renderer.pages[ s_renderer.currentPage ];
    
    // clear current page:
    graphics_setRenderTarget( &pPage->fgTarget );
    graphics_setBlendMode( BlendMode_Disabled );
    graphics_setShader( 0 );

    // 
    graphics_clear( 0.0f, 0.0f, 0.0f, 0.0f );

    graphics_setRenderTarget( &pPage->burnTarget );
    graphics_clear( 0.0f, 0.0f, 0.0f, 0.0f );

    for( uint i = 0u; i < SYS_COUNTOF(s_renderer.burnHoles); ++i )
    {
        if( s_renderer.burnHoles[i].size>=0.0f)
        {
//            SYS_TRACE_DEBUG("bh[%i]=%f\n", i, s_renderer.burnHoles[i].size);
            drawBurnHole( &s_renderer.burnHoles[i] );
            s_renderer.burnHoles[i].size -= 0.1f;
        }
    }

    if( s_renderer.flipDuration > 0.0f )
    {
        s_renderer.flipTime = 0.0f;
    }
    else
    {
        // flip instantly:
        s_renderer.flipTime = -1.0f;
    }
    s_renderer.pageNumber++;

    float oldVariance=s_renderer.currentVariance;
    s_renderer.currentVariance=0.0f;
    renderer_setPen(Pen_PageNumber);
    // add the page number;
    float2 textPos;
    float2_set(&textPos,1.0f,1.0f);
    char numberText[16u];
    sprintf(numberText,"%i",s_renderer.pageNumber);
    font_drawText(&textPos,0.5f,0.0f,numberText);

    renderer_flush();

    s_renderer.currentVariance=oldVariance;
    //font_
}
示例#7
0
void renderer_init()
{
    SYS_VERIFY( shader_create( &s_renderer.paperShader, &s_shader_paper, 1u, 1u, 0u ) );
    SYS_VERIFY( shader_create( &s_renderer.penShader, &s_shader_pen, 0u, 2u, 0u ) );
    SYS_VERIFY( shader_create( &s_renderer.pageShader, &s_shader_page, 0u, 0u, 3u ) );
    SYS_VERIFY( shader_create( &s_renderer.pageFlipShader, &s_shader_pageflip, 1u, 0u, 2u ) );
    SYS_VERIFY( shader_create( &s_renderer.burnHoleShader, &s_shader_burnhole, 0u, 2u, 1u ) );
    SYS_VERIFY( shader_create( &s_renderer.noiseShader, &s_shader_noise, 0u, 0u, 0u ) );
#ifndef SYS_BUILD_MASTER
    SYS_VERIFY( shader_create( &s_renderer.debugPenShader, &s_shader_debugpen, 1u, 0u, 0u ) );
#endif

    SYS_VERIFY( rendertarget_create( &s_renderer.noiseTarget, 512u, 512u, PixelFormat_R8G8B8A8 ) );
    
    graphics_setBlendMode( BlendMode_Disabled );

    // fill noise map:
    graphics_setRenderTarget( &s_renderer.noiseTarget );
    graphics_setShader( &s_renderer.noiseShader );
    graphics_drawFullscreenQuad();
    
    const int width = sys_getScreenWidth();
    const int height = sys_getScreenHeight();

    // create page:
    for( uint i = 0u; i < SYS_COUNTOF( s_renderer.pages ); ++i )
    {
        page_create( &s_renderer.pages[ i ], width, height );
    }

    s_renderer.currentPage = 0u;
    s_renderer.lastPage = 1u;
    
    s_renderer.currentCommand = 0u;

    s_renderer.pageNumber = 0u;

    s_renderer.pageState = PageState_Done;
    s_renderer.stateTime = 0.0f;

    clearStrokeBuffer( &s_renderer.strokeBuffer );

    float3 color;
    color.x = 0.2f;
    color.y = 0.2f;
    color.z = 0.2f;
    createPen( &s_renderer.pens[ Pen_Default ], 2.0f, 1.0f, &color );
    createPen( &s_renderer.pens[ Pen_Font ], 2.0f, 1.0f, &color );
    createPen( &s_renderer.pens[ Pen_Fat ], 3.0f, 1.0f, &color );
    createPen( &s_renderer.pens[ Pen_DebugRed ], 2.0f, 1.0f, float3_set( &color, 1.0f, 0.0f, 0.0f ) );
    createPen( &s_renderer.pens[ Pen_DebugGreen ], 2.0f, 1.0f, float3_set( &color, 0.0f, 1.0f, 0.0f ) );
    createPen( &s_renderer.pens[ Pen_PageNumber ], 2.0f, 1.0f, float3_set( &color, 0.0f, 0.0f, 0.0f ) );

    // create page flip mesh:
    createPageFlipMesh( &s_renderer.pageFlipMesh, 64u, 36u );

    s_renderer.flipTime = -1.0f;

    for( uint i = 0u; i < SYS_COUNTOF(s_renderer.burnHoles); ++i )
    {
        s_renderer.burnHoles[i].size = -1.0f;
    }

    renderer_setDrawSpeed( 0.5f );
    renderer_setPen( Pen_Default );
    renderer_setTransform( 0 );
}
示例#8
0
static int advanceStroke( float* pRemainingTime, float timeStep )
{
    // draw stroke..
    Page* pPage = &s_renderer.pages[ s_renderer.currentPage ];
    Stroke* pStroke = &s_renderer.currentStroke;
    const StrokeCommand* pCommand = &s_renderer.strokeBuffer.commands[ s_renderer.currentCommand ];

    if( !pCommand || pCommand->type != StrokeCommandType_Draw )
    {
        SYS_TRACE_ERROR( "no active stroke!\n" );
        return FALSE;
    }
    
    const StrokeDrawCommandData* pDrawCommand = &pCommand->data.draw;

    graphics_setRenderTarget( &pPage->fgTarget );
    graphics_setShader( &s_renderer.penShader );
    graphics_setBlendMode( BlendMode_Over );

    const PenDefinition* pPen = &s_renderer.pens[ pDrawCommand->penId ];
    const float variance = pDrawCommand->variance;

    // set constant shader parameters:
    graphics_setFp4f( 0u, 0.5f * pPen->width, variance, 0.05f * variance, 0.0f );
    graphics_setFp4f( 1u, pPen->color.x, pPen->color.y, pPen->color.z, 1.0f );

    float currentProgress = pStroke->progress;
    const float strokeLength = pStroke->length;
    
    float newProgress;
    if( s_renderer.strokeDrawSpeed <= 0.0f )
    {
        // always finish the whole stroke:
        newProgress = strokeLength;

        // and we don't need any time:
        *pRemainingTime = timeStep;
    }
    else
    {
        // how long until we reach the end of this stroke?:
        const float remainingStrokeTime = ( strokeLength - pStroke->progress ) / s_renderer.strokeDrawSpeed;        
        const float usedTime = float_min( timeStep, remainingStrokeTime );

        newProgress = pStroke->progress + usedTime * s_renderer.strokeDrawSpeed;
        *pRemainingTime = timeStep - usedTime;
    }

//    SYS_TRACE_DEBUG( "advancing stroke from %f to %f! length=%f\n", currentProgress, newProgress, strokeLength );

    if( newProgress <= currentProgress )
    {
        return TRUE;
    }

    const uint segmentCount = pDrawCommand->pointCount - 1u;
    float remainingLength = newProgress - currentProgress;

    const float2* pStrokePoints = &s_renderer.strokeBuffer.points[ pDrawCommand->pointIndex ];
    const float2* pStrokeNormals = &s_renderer.strokeBuffer.pointNormals[ pDrawCommand->pointIndex ];
    
    while( pStroke->activeSegment < segmentCount && remainingLength > 0.0f )
    {
        const float2 segmentStart = pStrokePoints[ pStroke->activeSegment ];
        const float2 segmentEnd = pStrokePoints[ pStroke->activeSegment + 1u ];
        const float2 segmentNormalStart = pStrokeNormals[ pStroke->activeSegment ];
        const float2 segmentNormalEnd = pStrokeNormals[ pStroke->activeSegment + 1u ];

        // get remaining length in current segment:
        float activeSegmentLength = float2_distance( &segmentStart, &segmentEnd );

        if( activeSegmentLength <= 0.0f )
        {
            break;
        }

        float remainingSegmentLength = activeSegmentLength - pStroke->segmentProgress;
        const float segmentAdvance = float_min( remainingSegmentLength, remainingLength );

        // draw segment part:
        const float partStart = pStroke->segmentProgress;
        const float partEnd = partStart + segmentAdvance;

        const float strokeU0 = currentProgress / strokeLength;
        const float strokeU1 = ( currentProgress + segmentAdvance ) / strokeLength;

        const float segmentU0 = partStart / activeSegmentLength;
        const float segmentU1 = partEnd / activeSegmentLength;
        
        // draw the active segment between partStart and partEnd:
        //SYS_TRACE_DEBUG( "drawing segment part from %f to %f!\n", partStart / activeSegmentLength, partEnd / activeSegmentLength );
           
        // compute part 

        // :todo: draw start and end parts if this is the start/end of the segment

        // compute coordinates of quad enclosing the segment part:
        float2 segmentDir;
        float2_normalize( float2_sub( &segmentDir, &segmentEnd, &segmentStart ) );
    
        float2 normalStart, normalEnd;
        float2_lerp( &normalStart, &segmentNormalStart, &segmentNormalEnd, segmentU0 );
        float2_lerp( &normalEnd, &segmentNormalStart, &segmentNormalEnd, segmentU1 );

        float2 startPos, endPos;
        float2_addScaled1f( &startPos, &segmentStart, &segmentDir, partStart );
        float2_addScaled1f( &endPos, &segmentStart, &segmentDir, partEnd );

        const float ws = 2.0f * ( 64.0f / sys_getScreenWidth() );
        
        float2 vertices[ 4u ];
        float2_addScaled1f( &vertices[ 0u ], &startPos, &normalStart,  ws * pPen->width );
        float2_addScaled1f( &vertices[ 1u ], &startPos, &normalStart, -ws * pPen->width );
        float2_addScaled1f( &vertices[ 2u ], &endPos, &normalEnd, -ws * pPen->width );
        float2_addScaled1f( &vertices[ 3u ], &endPos, &normalEnd,  ws * pPen->width );

        const float u0 = strokeU0;
        const float u1 = strokeU1;

        //SYS_TRACE_DEBUG( "u0=%f u1=%f v0=%f,%f v3=%f,%f\n", u0, u1, vertices[ 0u ].x, vertices[ 0u ].y, vertices[ 3u ].x, vertices[ 3u ].y );

        graphics_drawQuad( vertices, u0, 0.0f, u1, 1.0f );
        
        pStroke->segmentProgress += segmentAdvance;
        remainingLength -= segmentAdvance;
        currentProgress += segmentAdvance;

        if( segmentAdvance >= remainingSegmentLength )
        {
            // next segment:
            pStroke->activeSegment++;
            pStroke->segmentProgress = 0.0f;
        }
    }

    if( newProgress < strokeLength )
    {
        pStroke->progress = newProgress;  
        return TRUE;
    }

    return FALSE;
}
示例#9
0
文件: graphics.c 项目: ezhangle/motor
void graphics_init(int width, int height) {
  SDL_Init(SDL_INIT_VIDEO);
  //#ifdef EMSCRIPTEN
  //  moduleData.surface = SDL_SetVideoMode(width, height, 0, SDL_OPENGL);
  //#else
  #ifndef EMSCRIPTEN
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
  #else
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
  #endif
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    #if EMSCRIPTEN
      char const * title = emscripten_run_script_string("document.title");
    #else
      char const * title = "Motor2D";
    #endif

    moduleData.window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL);

    moduleData.context = SDL_GL_CreateContext(moduleData.window);
    SDL_GL_MakeCurrent(moduleData.window, moduleData.context);

    moduleData.surface = SDL_GetWindowSurface(moduleData.window);
    glewExperimental = GL_TRUE;

    printf("%d\n", glewInit());
  #ifndef EMSCRIPTEN
    SDL_GL_SetSwapInterval(1);
  #endif

  //#endif

//  glViewport(0,0,width,height);

  matrixstack_init();

  graphics_canvas_init(width, height);

  graphics_setColor(1.0f, 1.0f, 1.0f, 1.0f);

  graphics_geometry_init();
  graphics_font_init();
  graphics_batch_init();
  graphics_image_init();
  graphics_shader_init();

  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);

  graphics_setColorMask(true, true, true, true);
  graphics_setBlendMode(graphics_BlendMode_alpha);
  glEnable(GL_BLEND);
  graphics_clearScissor();

  glGenVertexArrays(1, &moduleData.polygonVAO);
  glBindVertexArray(moduleData.polygonVAO);
  glGenBuffers(1, &moduleData.polygonVBO);
  glGenBuffers(1, &moduleData.polygonIBO);
}