Follow-up to #64.
- Removed NEW_SLIDER option, and use the skin "SliderStyle" instead. Uses the new style by default, unless STYLE_PEPPYSLIDER is specified. - Check if OpenGL 3.0 is supported before trying to draw new style sliders. - Fixed compilation warnings; removed unneeded fields and imports. - Filled in some missing Javadocs. - Style changes. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
@@ -18,12 +18,13 @@
|
||||
package itdelatrisu.opsu.render;
|
||||
|
||||
import itdelatrisu.opsu.GameImage;
|
||||
import itdelatrisu.opsu.Options;
|
||||
import itdelatrisu.opsu.Utils;
|
||||
import itdelatrisu.opsu.beatmap.HitObject;
|
||||
import itdelatrisu.opsu.objects.curves.Vec2f;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
@@ -38,45 +39,46 @@ import org.newdawn.slick.util.Log;
|
||||
/**
|
||||
* Hold the temporary render state that needs to be restored again after the new
|
||||
* style curves are drawn.
|
||||
*
|
||||
* @author Bigpet {@literal <dravorek (at) gmail.com>}
|
||||
*/
|
||||
public class CurveRenderState {
|
||||
|
||||
/** The width and height of the display container this curve gets drawn into */
|
||||
/** The width and height of the display container this curve gets drawn into. */
|
||||
protected static int containerWidth, containerHeight;
|
||||
|
||||
/** cached drawn slider, only used if new style sliders are activated */
|
||||
public Rendertarget fbo;
|
||||
|
||||
/** thickness of the curve */
|
||||
/** Thickness of the curve. */
|
||||
protected static int scale;
|
||||
|
||||
/** The HitObject associated with the curve to be drawn */
|
||||
HitObject hitObject;
|
||||
|
||||
/** Static state that's needed to draw the new style curves */
|
||||
/** Static state that's needed to draw the new style curves. */
|
||||
private static final NewCurveStyleState staticState = new NewCurveStyleState();
|
||||
|
||||
/** Cached drawn slider, only used if new style sliders are activated. */
|
||||
public Rendertarget fbo;
|
||||
|
||||
/** The HitObject associated with the curve to be drawn. */
|
||||
protected HitObject hitObject;
|
||||
|
||||
/**
|
||||
* Set the width and height of the container that Curves get drawn into
|
||||
* Set the width and height of the container that Curves get drawn into.
|
||||
* Should be called before any curves are drawn.
|
||||
* @param width
|
||||
* @param height
|
||||
* @param width the container width
|
||||
* @param height the container height
|
||||
* @param circleSize the circle size
|
||||
*/
|
||||
public static void init(int width, int height, float circleSize)
|
||||
{
|
||||
public static void init(int width, int height, float circleSize) {
|
||||
containerWidth = width;
|
||||
containerHeight = height;
|
||||
//equivalent to what happens in Slider.init
|
||||
|
||||
// equivalent to what happens in Slider.init()
|
||||
scale = (int) (104 - (circleSize * 8));
|
||||
scale = (int) (scale * HitObject.getXMultiplier()); // convert from Osupixels (640x480)
|
||||
//scale = scale * 118 / 128; //for curves exaclty as big as the sliderball
|
||||
//scale = scale * 118 / 128; //for curves exactly as big as the sliderball
|
||||
FrameBufferCache.init(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an object to hold the render state that's necessary to draw a curve.
|
||||
* @param hitObject the HitObject that represents this curve, just used as a
|
||||
* unique ID
|
||||
* @param hitObject the HitObject that represents this curve, just used as a unique ID
|
||||
*/
|
||||
public CurveRenderState(HitObject hitObject) {
|
||||
fbo = null;
|
||||
@@ -92,13 +94,13 @@ public class CurveRenderState {
|
||||
*/
|
||||
public void draw(Color color, Vec2f[] curve) {
|
||||
float alpha = color.a;
|
||||
//if this curve hasn't been drawn, draw it and cache the result
|
||||
|
||||
// if this curve hasn't been drawn, draw it and cache the result
|
||||
if (fbo == null) {
|
||||
FrameBufferCache cache = FrameBufferCache.getInstance();
|
||||
Rendertarget mapping = cache.get(hitObject);
|
||||
if (mapping == null) {
|
||||
if (mapping == null)
|
||||
mapping = cache.insert(hitObject);
|
||||
}
|
||||
fbo = mapping;
|
||||
|
||||
int old_fb = GL11.glGetInteger(GL30.GL_FRAMEBUFFER_BINDING);
|
||||
@@ -116,8 +118,8 @@ public class CurveRenderState {
|
||||
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, old_fb);
|
||||
Utils.COLOR_WHITE_FADE.a = alpha;
|
||||
}
|
||||
|
||||
//draw a fullscreen quad with the texture that contains the curve
|
||||
|
||||
// draw a fullscreen quad with the texture that contains the curve
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_1D);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbo.getTextureID());
|
||||
@@ -134,15 +136,18 @@ public class CurveRenderState {
|
||||
GL11.glEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Discard the cache.
|
||||
*/
|
||||
public void discardCache() {
|
||||
fbo = null;
|
||||
FrameBufferCache.getInstance().freeMappingFor(hitObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just a structure to hold all the important OpenGL state that needs to be
|
||||
* A structure to hold all the important OpenGL state that needs to be
|
||||
* changed to draw the curve. This is used to backup and restore the state
|
||||
* so that the code outside of this (mainly Slick2D) doesn't break
|
||||
* so that the code outside of this (mainly Slick2D) doesn't break.
|
||||
*/
|
||||
private class RenderState {
|
||||
boolean smoothedPoly;
|
||||
@@ -157,8 +162,7 @@ public class CurveRenderState {
|
||||
|
||||
/**
|
||||
* Backup the current state of the relevant OpenGL state and change it to
|
||||
* what's needed to draw the curve
|
||||
* @return
|
||||
* what's needed to draw the curve.
|
||||
*/
|
||||
private RenderState startRender() {
|
||||
RenderState state = new RenderState();
|
||||
@@ -182,7 +186,7 @@ public class CurveRenderState {
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_1D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_1D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_1D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
|
||||
|
||||
|
||||
GL20.glUseProgram(0);
|
||||
|
||||
GL11.glMatrixMode(GL11.GL_PROJECTION);
|
||||
@@ -196,7 +200,7 @@ public class CurveRenderState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the old OpenGL state that's backed up in {@code state}
|
||||
* Restore the old OpenGL state that's backed up in {@code state}.
|
||||
* @param state the old state to restore
|
||||
*/
|
||||
private void endRender(RenderState state) {
|
||||
@@ -208,21 +212,16 @@ public class CurveRenderState {
|
||||
GL20.glUseProgram(state.oldProgram);
|
||||
GL13.glActiveTexture(state.texUnit);
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, state.oldArrayBuffer);
|
||||
if (!state.depthWriteEnabled) {
|
||||
if (!state.depthWriteEnabled)
|
||||
GL11.glDepthMask(false);
|
||||
}
|
||||
if (!state.depthEnabled) {
|
||||
if (!state.depthEnabled)
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
}
|
||||
if (state.texEnabled) {
|
||||
if (state.texEnabled)
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
}
|
||||
if (state.smoothedPoly) {
|
||||
if (state.smoothedPoly)
|
||||
GL11.glEnable(GL11.GL_POLYGON_SMOOTH);
|
||||
}
|
||||
if (!state.blendEnabled) {
|
||||
if (!state.blendEnabled)
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,14 +233,14 @@ public class CurveRenderState {
|
||||
staticState.initGradient();
|
||||
RenderState state = startRender();
|
||||
int vtx_buf;
|
||||
//The size is: floatsize * (position + texture coordinates) * (number of cones) * (vertices in a cone)
|
||||
// the size is: floatsize * (position + texture coordinates) * (number of cones) * (vertices in a cone)
|
||||
FloatBuffer buff = BufferUtils.createByteBuffer(4 * (4 + 2) * (2 * curve.length - 1) * (NewCurveStyleState.DIVIDES + 2)).asFloatBuffer();
|
||||
staticState.initShaderProgram();
|
||||
vtx_buf = GL15.glGenBuffers();
|
||||
for (int i = 0; i < curve.length; ++i) {
|
||||
float x = curve[i].x;
|
||||
float y = curve[i].y;
|
||||
//if(i == 0 || i==curve.length-1){
|
||||
//if (i == 0 || i == curve.length - 1){
|
||||
fillCone(buff, x, y, NewCurveStyleState.DIVIDES);
|
||||
if (i != 0) {
|
||||
float last_x = curve[i - 1].x;
|
||||
@@ -265,9 +264,8 @@ public class CurveRenderState {
|
||||
//2*4 is for skipping the first 2 floats (u,v)
|
||||
GL20.glVertexAttribPointer(staticState.attribLoc, 4, GL11.GL_FLOAT, false, 6 * 4, 2 * 4);
|
||||
GL20.glVertexAttribPointer(staticState.texCoordLoc, 2, GL11.GL_FLOAT, false, 6 * 4, 0);
|
||||
for (int i = 0; i < curve.length*2-1; ++i) {
|
||||
for (int i = 0; i < curve.length * 2 - 1; ++i)
|
||||
GL11.glDrawArrays(GL11.GL_TRIANGLE_FAN, i * (NewCurveStyleState.DIVIDES + 2), NewCurveStyleState.DIVIDES + 2);
|
||||
}
|
||||
GL20.glDisableVertexAttribArray(staticState.texCoordLoc);
|
||||
GL20.glDisableVertexAttribArray(staticState.attribLoc);
|
||||
GL15.glDeleteBuffers(vtx_buf);
|
||||
@@ -277,7 +275,7 @@ public class CurveRenderState {
|
||||
/**
|
||||
* Fill {@code buff} with the texture coordinates and positions for a cone
|
||||
* with {@code DIVIDES} ground corners that has its center at the coordinates
|
||||
* {@code (x1,y1)}
|
||||
* {@code (x1,y1)}.
|
||||
* @param buff the buffer to be filled
|
||||
* @param x1 x-coordinate of the cone
|
||||
* @param y1 y-coordinate of the cone
|
||||
@@ -332,57 +330,53 @@ public class CurveRenderState {
|
||||
* @author Bigpet {@literal <dravorek (at) gmail.com>}
|
||||
*/
|
||||
private static class NewCurveStyleState {
|
||||
|
||||
/**
|
||||
* used for new style Slider rendering, defines how many vertices the
|
||||
* base of the cone has that is used to draw the curve
|
||||
* Used for new style Slider rendering, defines how many vertices the
|
||||
* base of the cone has that is used to draw the curve.
|
||||
*/
|
||||
protected static final int DIVIDES = 30;
|
||||
|
||||
/** OpenGL shader program ID used to draw and recolor the curve */
|
||||
/** OpenGL shader program ID used to draw and recolor the curve. */
|
||||
protected int program = 0;
|
||||
|
||||
/** OpenGL shader attribute location of the vertex position attribute */
|
||||
/** OpenGL shader attribute location of the vertex position attribute. */
|
||||
protected int attribLoc = 0;
|
||||
|
||||
/** OpenGL shader attribute location of the texture coordinate attribute */
|
||||
/** OpenGL shader attribute location of the texture coordinate attribute. */
|
||||
protected int texCoordLoc = 0;
|
||||
|
||||
/** OpenGL shader uniform location of the color attribute */
|
||||
/** OpenGL shader uniform location of the color attribute. */
|
||||
protected int colLoc = 0;
|
||||
|
||||
/** OpenGL shader uniform location of the texture sampler attribute */
|
||||
/** OpenGL shader uniform location of the texture sampler attribute. */
|
||||
protected int texLoc = 0;
|
||||
|
||||
/** OpenGL texture id for the gradient texture for the curve */
|
||||
/** OpenGL texture id for the gradient texture for the curve. */
|
||||
protected int gradientTexture = 0;
|
||||
|
||||
/**
|
||||
* Reads the first row of the slider gradient texture and upload it as
|
||||
* a 1D texture to OpenGL if it hasn't already been done
|
||||
* a 1D texture to OpenGL if it hasn't already been done.
|
||||
*/
|
||||
public void initGradient()
|
||||
{
|
||||
if(gradientTexture == 0)
|
||||
{
|
||||
Image slider = GameImage.SLIDER_GRADIENT.getImage().getScaledCopy(1.0f/GameImage.getUIscale());
|
||||
public void initGradient() {
|
||||
if (gradientTexture == 0) {
|
||||
Image slider = GameImage.SLIDER_GRADIENT.getImage().getScaledCopy(1.0f / GameImage.getUIscale());
|
||||
staticState.gradientTexture = GL11.glGenTextures();
|
||||
ByteBuffer buff = BufferUtils.createByteBuffer(slider.getWidth()*4);
|
||||
for(int i=0 ; i< slider.getWidth(); ++i)
|
||||
{
|
||||
ByteBuffer buff = BufferUtils.createByteBuffer(slider.getWidth() * 4);
|
||||
for (int i = 0; i < slider.getWidth(); ++i) {
|
||||
Color col = slider.getColor(i, 0);
|
||||
buff.put((byte)(255*col.r));
|
||||
buff.put((byte)(255*col.g));
|
||||
buff.put((byte)(255*col.b));
|
||||
buff.put((byte)(255*col.a));
|
||||
buff.put((byte) (255 * col.r));
|
||||
buff.put((byte) (255 * col.g));
|
||||
buff.put((byte) (255 * col.b));
|
||||
buff.put((byte) (255 * col.a));
|
||||
}
|
||||
buff.flip();
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_1D, gradientTexture);
|
||||
GL11.glTexImage1D(GL11.GL_TEXTURE_1D,0,GL11.GL_RGBA,slider.getWidth(),0,GL11.GL_RGBA,GL11.GL_UNSIGNED_BYTE,buff);
|
||||
GL11.glTexImage1D(GL11.GL_TEXTURE_1D, 0, GL11.GL_RGBA, slider.getWidth(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buff);
|
||||
GL30.glGenerateMipmap(GL11.GL_TEXTURE_1D);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compiles and links the shader program for the new style curve objects
|
||||
* if it hasn't already been compiled and linked.
|
||||
@@ -407,7 +401,7 @@ public class CurveRenderState {
|
||||
int res = GL20.glGetShaderi(vtxShdr, GL20.GL_COMPILE_STATUS);
|
||||
if (res != GL11.GL_TRUE) {
|
||||
String error = GL20.glGetShaderInfoLog(vtxShdr, 1024);
|
||||
Log.error("Vertex Shader compilation failed", new Exception(error));
|
||||
Log.error("Vertex Shader compilation failed.", new Exception(error));
|
||||
}
|
||||
GL20.glShaderSource(frgShdr, "#version 330\n"
|
||||
+ "\n"
|
||||
@@ -429,7 +423,7 @@ public class CurveRenderState {
|
||||
res = GL20.glGetShaderi(frgShdr, GL20.GL_COMPILE_STATUS);
|
||||
if (res != GL11.GL_TRUE) {
|
||||
String error = GL20.glGetShaderInfoLog(frgShdr, 1024);
|
||||
Log.error("Fragment Shader compilation failed", new Exception(error));
|
||||
Log.error("Fragment Shader compilation failed.", new Exception(error));
|
||||
}
|
||||
GL20.glAttachShader(program, vtxShdr);
|
||||
GL20.glAttachShader(program, frgShdr);
|
||||
@@ -437,7 +431,7 @@ public class CurveRenderState {
|
||||
res = GL20.glGetProgrami(program, GL20.GL_LINK_STATUS);
|
||||
if (res != GL11.GL_TRUE) {
|
||||
String error = GL20.glGetProgramInfoLog(program, 1024);
|
||||
Log.error("Program linking failed", new Exception(error));
|
||||
Log.error("Program linking failed.", new Exception(error));
|
||||
}
|
||||
attribLoc = GL20.glGetAttribLocation(program, "in_position");
|
||||
texCoordLoc = GL20.glGetAttribLocation(program, "in_tex_coord");
|
||||
|
||||
Reference in New Issue
Block a user