New optional slider style
New slider rendering works by rendering the slider to an offscreen buffer Add CurveRenderState.java and FrameBufferCache.java that were forgotten in the last commit
This commit is contained in:
123
src/itdelatrisu/opsu/render/FrameBufferCache.java
Normal file
123
src/itdelatrisu/opsu/render/FrameBufferCache.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* opsu! - an open-source osu! client
|
||||
* Copyright (C) 2014, 2015 Jeffrey Han
|
||||
*
|
||||
* opsu! is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu! is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package itdelatrisu.opsu.render;
|
||||
|
||||
import itdelatrisu.opsu.Options;
|
||||
import itdelatrisu.opsu.beatmap.HitObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.newdawn.slick.util.Log;
|
||||
|
||||
/**
|
||||
* This is cache for OpenGL FrameBufferObjects. This is currently only used
|
||||
* to draw curve objects of the new slider style. Does currently not integrate
|
||||
* well and requires some manual OpenGL state manipulation to use it.
|
||||
* @author Bigpet {@literal <dravorek@gmail.com>}
|
||||
*/
|
||||
public class FrameBufferCache {
|
||||
private static final int INITIAL_CACHE_SIZE = 4;
|
||||
private static FrameBufferCache instance = null;
|
||||
private Map<HitObject, Rendertarget> cacheMap;
|
||||
private ArrayList<Rendertarget> cache;
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
private FrameBufferCache(int width, int height) {
|
||||
cache = new ArrayList<>(INITIAL_CACHE_SIZE);
|
||||
cacheMap = new HashMap<>();
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
for (int i = 0; i < INITIAL_CACHE_SIZE; ++i) {
|
||||
cache.add(Rendertarget.createRTTFramebuffer(width, height));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is a framebuffer object mapped to the {@code HitObject obj}
|
||||
* @param obj
|
||||
* @return true if there is a framebuffer mapped for this HitObject, else false
|
||||
*/
|
||||
public boolean contains(HitObject obj) {
|
||||
return cacheMap.containsKey(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@code Rendertarget} mapped to {@code obj}
|
||||
* @param obj
|
||||
* @return the {@code Rendertarget} if there's one mapped to {@code obj}, otherwise null
|
||||
*/
|
||||
public Rendertarget get(HitObject obj) {
|
||||
return cacheMap.get(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the mapping for {@code obj} to free it up to get used by another {@code HitObject}
|
||||
* @param obj
|
||||
* @return true if there was a mapping for {@code obj} and false if there was no mapping for it.
|
||||
*/
|
||||
public boolean freeMappingFor(HitObject obj) {
|
||||
return cacheMap.remove(obj) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the cache of all the mappings. This does not actually delete the
|
||||
* cached framebuffers, it merely frees them all up to get mapped anew.
|
||||
*/
|
||||
public void freeMap() {
|
||||
cacheMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mapping from {@code obj} to a framebuffer. If there was already
|
||||
* a mapping from {@code obj} this will associate another framebuffer with it
|
||||
* (thereby freeing up the previously mapped framebuffer).
|
||||
* @param obj
|
||||
* @return the {@code Rendertarget} newly mapped to {@code obj}
|
||||
*/
|
||||
public Rendertarget insert(HitObject obj) {
|
||||
//find first RTTFramebuffer that's not mapped to anything and return it
|
||||
Rendertarget buffer;
|
||||
for (int i = 0; i < cache.size(); ++i) {
|
||||
buffer = cache.get(i);
|
||||
if (!cacheMap.containsValue(buffer)) {
|
||||
cacheMap.put(obj, buffer);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
//no unmapped RTTFramebuffer found, create a new one
|
||||
buffer = Rendertarget.createRTTFramebuffer(width, height);
|
||||
cache.add(buffer);
|
||||
Log.warn("Framebuffer cache was not large enough, possible resource leak.");
|
||||
cacheMap.put(obj, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* There should only ever be one framebuffer cache, this function returns that one framebuffer cache instance.
|
||||
* If there was no instance created already then this function creates it.
|
||||
* @return the instance of FrameBufferCache
|
||||
*/
|
||||
public static FrameBufferCache getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new FrameBufferCache(Options.getLatestResolutionWidth(), Options.getLatestResolutionHeight());
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user