static void drawVertices(JNIEnv* env, jobject, jlong canvasHandle,
                         jint modeHandle, jint vertexCount,
                         jfloatArray jverts, jint vertIndex,
                         jfloatArray jtexs, jint texIndex,
                         jintArray jcolors, jint colorIndex,
                         jshortArray jindices, jint indexIndex,
                         jint indexCount, jlong paintHandle) {
    AutoJavaFloatArray  vertA(env, jverts, vertIndex + vertexCount);
    AutoJavaFloatArray  texA(env, jtexs, texIndex + vertexCount);
    AutoJavaIntArray    colorA(env, jcolors, colorIndex + vertexCount);
    AutoJavaShortArray  indexA(env, jindices, indexIndex + indexCount);

    const float* verts = vertA.ptr() + vertIndex;
    const float* texs = texA.ptr() + vertIndex;
    const int* colors = NULL;
    const uint16_t* indices = NULL;

    if (jcolors != NULL) {
        colors = colorA.ptr() + colorIndex;
    }
    if (jindices != NULL) {
        indices = (const uint16_t*)(indexA.ptr() + indexIndex);
    }

    SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle);
    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
    get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors,
                                           indices, indexCount, *paint);
}
Пример #2
0
    static void drawVertices(JNIEnv* env, jobject, SkCanvas* canvas,
                             SkCanvas::VertexMode mode, int vertexCount,
                             jfloatArray jverts, int vertIndex,
                             jfloatArray jtexs, int texIndex,
                             jintArray jcolors, int colorIndex,
                             jshortArray jindices, int indexIndex,
                             int indexCount, const SkPaint* paint) {

        AutoJavaFloatArray  vertA(env, jverts, vertIndex + vertexCount);
        AutoJavaFloatArray  texA(env, jtexs, texIndex + vertexCount);
        AutoJavaIntArray    colorA(env, jcolors, colorIndex + vertexCount);
        AutoJavaShortArray  indexA(env, jindices, indexIndex + indexCount);

        const int ptCount = vertexCount >> 1;

        SkPoint* verts;
        SkPoint* texs = NULL;
#ifdef SK_SCALAR_IS_FLOAT
        verts = (SkPoint*)(vertA.ptr() + vertIndex);
        if (jtexs != NULL) {
            texs = (SkPoint*)(texA.ptr() + texIndex);
        }
#else
        int count = ptCount;    // for verts
        if (jtexs != NULL) {
            count += ptCount;   // += for texs
        }
        SkAutoMalloc storage(count * sizeof(SkPoint));
        verts = (SkPoint*)storage.get();        
        const float* src = vertA.ptr() + vertIndex;
        for (int i = 0; i < ptCount; i++) {
            verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
            src += 2;
        }
        if (jtexs != NULL) {
            texs = verts + ptCount;
            src = texA.ptr() + texIndex;
            for (int i = 0; i < ptCount; i++) {
                texs[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1]));
                src += 2;
            }
        }
#endif

        const SkColor* colors = NULL;
        const uint16_t* indices = NULL;
        if (jcolors != NULL) {
            colors = (const SkColor*)(colorA.ptr() + colorIndex);
        }
        if (jindices != NULL) {
            indices = (const uint16_t*)(indexA.ptr() + indexIndex);
        }

        canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL,
                             indices, indexCount, *paint);
    }
Пример #3
0
void liveAdvectTexture(){
	Window::init();
	Window window("Realtime Texture Advection");
	//Set an fps cap
	const float FPS = 60.0f;

	//Setup a quad to draw too
	GL::VertexArray vao;
	vao.elementBuffer(quadElems);
	GL::VertexBuffer vbo(quad, GL::USAGE::STATIC_DRAW);	

	//Setup program
	GL::Program prog("../res/shader.v.glsl", "../res/shader.f.glsl");
	
	//Setup the attributes
	vao.setAttribPointer(vbo, prog.getAttribute("position"), 3, GL_FLOAT, GL_FALSE);
	vao.setAttribPointer(vbo, prog.getAttribute("texIn"), 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * 4));
	
	glm::mat4 view = glm::lookAt<float>(glm::vec3(0, 0, 1), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0));
	glm::mat4 proj = glm::perspective(60.0f, (float)(window.box().w) /  (float)(window.box().h), 0.1f, 100.0f);
	glm::mat4 model = glm::scale(0.55f, 0.55f, 1.0f);
	glm::mat4 mvp = proj * view * model;
	prog.uniformMat4x4("mvp", mvp);

	/*
	* I don't think OpenCL or OpenGL provide a simple method for copying images/textures so 
	* instead we'll flip the in/out image each step and draw the out image by setting active = out
	*/
	//Make textures to work with
	GL::Texture texA("../res/map.png", true, SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB);
	GL::Texture texB("../res/blank.png", true, SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB);
	//Active is the actual texture we will draw
	GL::Texture active = texB;

	//Setup our OpenCL context + program and kernel
	CL::TinyCL tiny(CL::DEVICE::GPU, true);
	cl::Program program = tiny.loadProgram("../res/simpleAdvect.cl");
	cl::Kernel kernel = tiny.loadKernel(program, "simpleAdvect");

	//Setup our OpenCL data
#ifdef CL_VERSION_1_2
	cl::ImageGL imgA = tiny.imageFromTexture(CL::MEM::READ_WRITE, texA);
	cl::ImageGL imgB = tiny.imageFromTexture(CL::MEM::READ_WRITE, texB);
#else
	cl::Image2DGL imgA = tiny.imageFromTexture(CL::MEM::READ_WRITE, texA);
	cl::Image2DGL imgB = tiny.imageFromTexture(CL::MEM::READ_WRITE, texB);
#endif
	const float speed = 0.2f;
	float velocity[2] = { 0.0f, 0.0f };
	cl::Buffer velBuf = tiny.buffer(CL::MEM::READ_ONLY, 2 * sizeof(float), velocity);

	//Setup our GL objects vector
	std::vector<cl::Memory> glObjs;
	glObjs.push_back(imgA);
	glObjs.push_back(imgB);

	//The time step will be constant and velocity won't change each step, so set'em now
	float dt = 1.0f / FPS;
	kernel.setArg(0, sizeof(float), &dt);
	kernel.setArg(1, velBuf);
	
	//Query the preferred work group size
	int workSize = tiny.preferredWorkSize(kernel);
	//fixed for now
	int imgSize = 256;
	cl::NDRange local(workSize, workSize);
	cl::NDRange global(imgSize, imgSize);
	//Track the run number so we know which texture to set as in/out and which to draw
	int run = 0;

	//Our event structure
	SDL_Event e;
	//Limit framerate with a timer
	Timer delta;
	//For tracking if we want to quit
	bool quit = false, paused = false;
	while (!quit){
		delta.Start();
		//Event Polling
		while (SDL_PollEvent(&e)){
			//If user closes he window
			if (e.type == SDL_QUIT)
				quit = true;
			//If user presses any key
			if (e.type == SDL_KEYDOWN){
				switch (e.key.keysym.sym){
					//So we can change velocity
					case SDLK_w:
						velocity[1] = speed;
						tiny.writeData(velBuf, 2 * sizeof(float), velocity);
						break;
					case SDLK_s:
						velocity[1] = -speed;
						tiny.writeData(velBuf, 2 * sizeof(float), velocity);
						break;
					case SDLK_a:
						velocity[0] = -speed;
						tiny.writeData(velBuf, 2 * sizeof(float), velocity);
						break;
					case SDLK_d:
						velocity[0] = speed;
						tiny.writeData(velBuf, 2 * sizeof(float), velocity);
						break;
					case SDLK_r:
						velocity[0] = 0.0f;
						velocity[1] = 0.0f;
						tiny.writeData(velBuf, 2 * sizeof(float), velocity);
						break;
					//Toggle pause
					case SDLK_SPACE:
						paused = !paused;
						break;
					//For quitting, escape key
					case SDLK_ESCAPE:
						quit = true;
						break;
					default:
						break;
				}
			}
		}
		//Run the kernel, setting the in/out textures properly. On even runs the output will be
		//in texB, on odd runs output will be in texA
		if (!paused){
			try {
				//On even runs and the first run texB/imgB is our output, on odd runs it's flipped
				//Is this really the best way to do this? Maybe there is some faster way to copy the image over
				//instead of updating this each time
				if (run % 2 == 0 || run == 0){
					kernel.setArg(2, imgA);
					kernel.setArg(3, imgB);
					active = texB;
				}
				else {
					kernel.setArg(2, imgB);
					kernel.setArg(3, imgA);
					active = texA;
				}
				glFinish();
				tiny.mQueue.enqueueAcquireGLObjects(&glObjs);

				tiny.runKernel(kernel, local, global);
			
				tiny.mQueue.enqueueReleaseGLObjects(&glObjs);
				tiny.mQueue.finish();
				++run;
			}
			catch (const cl::Error &e){
				std::cout << "Error: " << e.what() << " code: " << e.err() << std::endl;
			}
		}
		//RENDERING
		window.clear();

		prog.use();
		glBindVertexArray(vao);
		glActiveTexture(GL_TEXTURE0);
		//Shouldn't we be drawing active here?
		glBindTexture(GL_TEXTURE_2D, texA);
		glDrawElements(GL_TRIANGLES, vao.numElements(), GL_UNSIGNED_SHORT, NULL);

		window.present();

		//Cap fps
		if (delta.Ticks() < 1000 / FPS)
			SDL_Delay(1000 / FPS - delta.Ticks());
	}
	window.close();
	Window::quit();
}