Home | History | Annotate | Download | only in GLFWTest
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "GLFW/glfw3.h"
      9 #include <stdlib.h>
     10 #include <stdio.h>
     11 
     12 #include "GrContext.h"
     13 
     14 #include "SkCanvas.h"
     15 #include "SkImage.h"
     16 #include "SkRSXform.h"
     17 #include "SkSurface.h"
     18 #include "Timer.h"
     19 
     20 GrContext* sContext = nullptr;
     21 SkSurface* sSurface = nullptr;
     22 
     23 static void error_callback(int error, const char* description) {
     24     fputs(description, stderr);
     25 }
     26 
     27 static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
     28     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
     29         glfwSetWindowShouldClose(window, GL_TRUE);
     30 }
     31 
     32 
     33 static void init_skia(int w, int h) {
     34     sContext = GrContext::Create(kOpenGL_GrBackend, 0);
     35 
     36     GrBackendRenderTargetDesc desc;
     37     desc.fWidth = w;
     38     desc.fHeight = h;
     39     desc.fConfig = kSkia8888_GrPixelConfig;
     40     desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     41     desc.fSampleCnt = 1;
     42     desc.fStencilBits = 0;
     43     desc.fRenderTargetHandle = 0;  // assume default framebuffer
     44 
     45     sSurface = SkSurface::MakeFromBackendRenderTarget(sContext, desc, nullptr, nullptr).release();
     46 }
     47 
     48 static void cleanup_skia() {
     49     delete sSurface;
     50     delete sContext;
     51 }
     52 
     53 const int kGrid = 100;
     54 const int kWidth = 960;
     55 const int kHeight = 640;
     56 
     57 int main(void) {
     58     GLFWwindow* window;
     59     glfwSetErrorCallback(error_callback);
     60     if (!glfwInit()) {
     61         exit(EXIT_FAILURE);
     62     }
     63 
     64     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
     65     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
     66     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
     67     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
     68     glfwWindowHint(GLFW_SRGB_CAPABLE, GL_TRUE);
     69 
     70     window = glfwCreateWindow(kWidth, kHeight, "Simple example", NULL, NULL);
     71     if (!window) {
     72         glfwTerminate();
     73         exit(EXIT_FAILURE);
     74     }
     75     glfwMakeContextCurrent(window);
     76 
     77     init_skia(kWidth, kHeight);
     78 
     79     sk_sp<SkImage> atlas;
     80     SkRSXform   xform[kGrid*kGrid+1];
     81     SkRect      tex[kGrid*kGrid+1];
     82     WallTimer   timer;
     83     float       times[32];
     84     int         currentTime;
     85 
     86     sk_sp<SkData> imageData(SkData::MakeFromFileName("ship.png"));
     87     atlas.reset(SkImage::NewFromEncoded(imageData.get()));
     88     if (!atlas) {
     89         SkDebugf("\nCould not decode file ship.png\n");
     90 
     91         cleanup_skia();
     92         glfwDestroyWindow(window);
     93         glfwTerminate();
     94         exit(EXIT_FAILURE);
     95     }
     96 
     97     SkScalar anchorX = atlas->width()*0.5f;
     98     SkScalar anchorY = atlas->height()*0.5f;
     99     int currIndex = 0;
    100     for (int x = 0; x < kGrid; x++) {
    101         for (int y = 0; y < kGrid; y++) {
    102             float xPos = (x / (kGrid - 1.0)) * kWidth;
    103             float yPos = (y / (kGrid - 1.0)) * kWidth;
    104 
    105             tex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f, atlas->width(), atlas->height());
    106             xform[currIndex] = SkRSXform::MakeFromRadians(2.0f, SK_ScalarPI*0.5f,
    107                                                           xPos, yPos, anchorX, anchorY);
    108             currIndex++;
    109         }
    110     }
    111     tex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f, atlas->width(), atlas->height());
    112     xform[currIndex] = SkRSXform::MakeFromRadians(2.0f, SK_ScalarPI*0.5f,
    113                                                   kWidth*0.5f, kHeight*0.5f, anchorX, anchorY);
    114 
    115     currentTime = 0;
    116 
    117     glfwSwapInterval(1);
    118     glfwSetKeyCallback(window, key_callback);
    119 
    120     // Draw to the surface via its SkCanvas.
    121     SkCanvas* canvas = sSurface->getCanvas();   // We don't manage this pointer's lifetime.
    122     SkPaint paint;
    123     paint.setFilterQuality(kLow_SkFilterQuality);
    124     paint.setColor(SK_ColorWHITE);
    125     paint.setTextSize(15.0f);
    126 
    127     while (!glfwWindowShouldClose(window)) {
    128         const float kCosDiff = 0.99984769515f;
    129         const float kSinDiff = 0.01745240643f;
    130 
    131         timer.start();
    132 
    133         glfwPollEvents();
    134 
    135         float meanTime = 0.0f;
    136         for (int i = 0; i < 32; ++i) {
    137             meanTime += times[i];
    138         }
    139         meanTime /= 32.f;
    140         char outString[64];
    141         float fps = 1000.f/meanTime;
    142         sprintf(outString, "fps: %f ms: %f", fps, meanTime);
    143 
    144         for (int i = 0; i < kGrid*kGrid+1; ++i) {
    145             SkScalar c = xform[i].fSCos;
    146             SkScalar s = xform[i].fSSin;
    147 
    148             SkScalar dx = c*anchorX - s*anchorY;
    149             SkScalar dy = s*anchorX + c*anchorY;
    150 
    151             xform[i].fSCos = kCosDiff*c - kSinDiff*s;
    152             xform[i].fSSin = kSinDiff*c + kCosDiff*s;
    153 
    154             dx -= xform[i].fSCos*anchorX - xform[i].fSSin*anchorY;
    155             dy -= xform[i].fSSin*anchorX + xform[i].fSCos*anchorY;
    156             xform[i].fTx += dx;
    157             xform[i].fTy += dy;
    158         }
    159 
    160         canvas->clear(SK_ColorBLACK);
    161         canvas->drawAtlas(atlas, xform, tex, nullptr, kGrid*kGrid+1, SkXfermode::kSrcOver_Mode,
    162                           nullptr, &paint);
    163         canvas->drawText(outString, strlen(outString), 100.f, 100.f, paint);
    164 
    165         canvas->flush();
    166 
    167         timer.end();
    168         times[currentTime] = (float)(timer.fWall);
    169         currentTime = (currentTime + 1) & 0x1f;
    170 
    171         glfwSwapBuffers(window);
    172     }
    173 
    174     cleanup_skia();
    175 
    176     glfwDestroyWindow(window);
    177     glfwTerminate();
    178     exit(EXIT_SUCCESS);
    179 }
    180