Shader tm
This commit is contained in:
parent
02448503c7
commit
9a3ecc06aa
15
res/sh_Cursor.vertex
Normal file
15
res/sh_Cursor.vertex
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
attribute vec4 m_Position;
|
||||||
|
attribute vec2 m_TexCoord;
|
||||||
|
attribute float m_Time;
|
||||||
|
|
||||||
|
varying vec4 v_Color;
|
||||||
|
varying vec2 v_TexCoord;
|
||||||
|
|
||||||
|
uniform float g_FadeClock;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = m_Position;
|
||||||
|
v_Color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
v_TexCoord = m_TexCoord;
|
||||||
|
}
|
13
res/sh_Texture.frag
Normal file
13
res/sh_Texture.frag
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec4 v_Color;
|
||||||
|
varying vec2 v_TexCoord;
|
||||||
|
|
||||||
|
uniform sampler2D m_Sampler;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);//v_Color * texture2D(m_Sampler, v_TexCoord);
|
||||||
|
}
|
92
src/com/osufx/sunpy/PropertyCollection.java
Normal file
92
src/com/osufx/sunpy/PropertyCollection.java
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package com.osufx.sunpy;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class PropertyCollection {
|
||||||
|
private HashMap<String, ShaderProperty> properties = new HashMap<>();
|
||||||
|
private Shader owner;
|
||||||
|
|
||||||
|
private boolean changed = false;
|
||||||
|
|
||||||
|
public PropertyCollection(Shader owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear() {
|
||||||
|
this.changed = true;
|
||||||
|
this.properties.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(ShaderProperty prop) {
|
||||||
|
this.properties.put(prop.Name, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Replace(ShaderProperty prop) {
|
||||||
|
this.properties.replace(prop.Name, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Replace(String key, Object value) {
|
||||||
|
if (!this.properties.containsKey(key))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ShaderProperty prop = this.properties.get(key);
|
||||||
|
|
||||||
|
if (value.getClass() != prop.Type){
|
||||||
|
System.out.println(String.format("%s variable %s does not take value type %s", this.owner.name, key, value.getClass()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop.Value != null && prop.Value == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prop.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(String key) {
|
||||||
|
this.properties.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set() {
|
||||||
|
if (!this.changed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (ShaderProperty prop : this.properties.values()) {
|
||||||
|
prop.Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShaderProperty get(String propName) {
|
||||||
|
if (!this.properties.containsKey(propName))
|
||||||
|
return null;
|
||||||
|
return this.properties.get(propName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(String propName, Object value) {
|
||||||
|
if (!this.owner.loaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!this.properties.containsKey(propName)) {
|
||||||
|
System.out.println(String.format("Property %s does not exist!", propName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderProperty prop = this.properties.get(propName);
|
||||||
|
|
||||||
|
if (value.getClass() != prop.Type){
|
||||||
|
System.out.println(String.format("%s variable %s does not take value type %s", this.owner.name, propName, value.getClass()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop.Value != null && prop.Value == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prop.Value = value;
|
||||||
|
|
||||||
|
if (this.owner.started)
|
||||||
|
prop.Set();
|
||||||
|
else
|
||||||
|
this.changed = true;
|
||||||
|
}
|
||||||
|
}
|
204
src/com/osufx/sunpy/Shader.java
Normal file
204
src/com/osufx/sunpy/Shader.java
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
package com.osufx.sunpy;
|
||||||
|
|
||||||
|
import org.lwjgl.BufferUtils;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.newdawn.slick.util.Log;
|
||||||
|
import org.newdawn.slick.util.ResourceLoader;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class Shader {
|
||||||
|
public String name;
|
||||||
|
public int programId = -1;
|
||||||
|
public boolean loaded = false;
|
||||||
|
public boolean started = false;
|
||||||
|
|
||||||
|
public PropertyCollection Properties;
|
||||||
|
|
||||||
|
public static HashMap<String, Object> globalProperties = new HashMap<>();
|
||||||
|
public static List<Shader> loadedShaders = new ArrayList<>();
|
||||||
|
public static int currentShader = 0;
|
||||||
|
|
||||||
|
private HashMap<String, Integer> attribLoc = new HashMap<>();
|
||||||
|
private static final String[] attribs = new String[] {
|
||||||
|
"m_Position",
|
||||||
|
"m_Color",
|
||||||
|
"m_TexCoord",
|
||||||
|
"m_Time",
|
||||||
|
"m_Direction"
|
||||||
|
};
|
||||||
|
|
||||||
|
private HashMap<Integer, String> shaderParts = new HashMap<>();
|
||||||
|
private int previousShader;
|
||||||
|
|
||||||
|
public Shader(String vertexShader, String fragmentShader) {
|
||||||
|
String vertexString;
|
||||||
|
String fragmentString;
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream vertexStream = ResourceLoader.getResourceAsStream(vertexShader);
|
||||||
|
vertexString = convertStreamToString(vertexStream);
|
||||||
|
|
||||||
|
InputStream fragmentStream = ResourceLoader.getResourceAsStream(fragmentShader);
|
||||||
|
fragmentString = convertStreamToString(fragmentStream);
|
||||||
|
} catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.name = String.format("%s/%s", vertexShader, fragmentShader);
|
||||||
|
this.Properties = new PropertyCollection(this);
|
||||||
|
|
||||||
|
this.programId = GL20.glCreateProgram();
|
||||||
|
|
||||||
|
this.shaderParts.put(GL20.glCreateShader(GL20.GL_VERTEX_SHADER), vertexString);
|
||||||
|
this.shaderParts.put(GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER), fragmentString);
|
||||||
|
this.CompileParts();
|
||||||
|
this.Compile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shader(String shader, final int shaderType) {
|
||||||
|
if (shaderType != GL20.GL_FRAGMENT_SHADER && shaderType != GL20.GL_VERTEX_SHADER){
|
||||||
|
System.out.println("Invalid shader type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String shaderString;
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream shaderStream = ResourceLoader.getResourceAsStream(shader);
|
||||||
|
shaderString = convertStreamToString(shaderStream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.name = String.format("%s/%s",
|
||||||
|
shaderType == GL20.GL_FRAGMENT_SHADER ? "Fragment" : "Vertex",
|
||||||
|
shader);
|
||||||
|
this.Properties = new PropertyCollection(this);
|
||||||
|
|
||||||
|
this.programId = GL20.glCreateProgram();
|
||||||
|
|
||||||
|
this.shaderParts.put(GL20.glCreateShader(shaderType), shaderString);
|
||||||
|
this.CompileParts();
|
||||||
|
this.Compile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CompileParts() {
|
||||||
|
for (Map.Entry<Integer, String> entry : this.shaderParts.entrySet()) {
|
||||||
|
int handle = entry.getKey();
|
||||||
|
String source = entry.getValue();
|
||||||
|
|
||||||
|
GL20.glShaderSource(handle, source);
|
||||||
|
GL20.glCompileShader(handle);
|
||||||
|
|
||||||
|
int res = GL20.glGetShaderi(handle, GL20.GL_COMPILE_STATUS);
|
||||||
|
if (res != GL11.GL_TRUE) {
|
||||||
|
String error = GL20.glGetShaderInfoLog(handle, 1024);
|
||||||
|
Log.error("Shader compilation failed.", new Exception(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Compile() {
|
||||||
|
this.Properties.Clear();
|
||||||
|
|
||||||
|
for (int handler : this.shaderParts.keySet()) {
|
||||||
|
GL20.glAttachShader(this.programId, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL20.glLinkProgram(this.programId);
|
||||||
|
|
||||||
|
int res = GL20.glGetProgrami(this.programId, GL20.GL_LINK_STATUS);
|
||||||
|
if (res != GL11.GL_TRUE) {
|
||||||
|
String error = GL20.glGetProgramInfoLog(this.programId, 1024);
|
||||||
|
Log.error("Program linking failed.", new Exception(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int handler : this.shaderParts.keySet()) {
|
||||||
|
GL20.glDeleteShader(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < attribs.length; i++) {
|
||||||
|
int attrib = GL20.glGetAttribLocation(this.programId, attribs[i]);
|
||||||
|
this.attribLoc.put(attribs[i], attrib);
|
||||||
|
//GL20.glBindAttribLocation(this.programId, i, attribLoc[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*for (int handler : this.shaderParts.keySet()) {
|
||||||
|
GL20.glDetachShader(this.programId, handler);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
this.loaded = res == GL11.GL_TRUE;
|
||||||
|
|
||||||
|
if (this.loaded) {
|
||||||
|
int uniCount = GL20.glGetProgrami(this.programId, GL20.GL_ACTIVE_UNIFORMS);
|
||||||
|
|
||||||
|
for (int i = 0; i < uniCount; i++) {
|
||||||
|
IntBuffer length = BufferUtils.createIntBuffer(1);
|
||||||
|
IntBuffer size = BufferUtils.createIntBuffer(1);
|
||||||
|
IntBuffer type = BufferUtils.createIntBuffer(1);
|
||||||
|
ByteBuffer name = ByteBuffer.allocateDirect(64);
|
||||||
|
|
||||||
|
GL20.glGetActiveUniform(this.programId, i, length, size, type, name);
|
||||||
|
|
||||||
|
|
||||||
|
byte[] buf = new byte[length.get(0)];
|
||||||
|
|
||||||
|
name.get(buf, 0, buf.length);
|
||||||
|
String propName = new String(buf);
|
||||||
|
int propLocation = GL20.glGetUniformLocation(programId, propName);
|
||||||
|
|
||||||
|
UniformType propUniformType = UniformType.map.get(type.get(0));
|
||||||
|
Class propType = ShaderProperty.ConvertType(propUniformType.name());
|
||||||
|
|
||||||
|
System.out.println(String.format("propName:%s PropUniformType:%s PropType:%s", propName, propUniformType, propType));
|
||||||
|
|
||||||
|
this.Properties.Add(new ShaderProperty(
|
||||||
|
propName,
|
||||||
|
propLocation,
|
||||||
|
propType,
|
||||||
|
propUniformType
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : globalProperties.entrySet()) {
|
||||||
|
this.Properties.Replace(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
loadedShaders.add(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Begin(){
|
||||||
|
if (this.started || !this.loaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GL20.glUseProgram(this.programId);
|
||||||
|
this.previousShader = currentShader;
|
||||||
|
currentShader = this.programId;
|
||||||
|
|
||||||
|
this.started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void End() {
|
||||||
|
if (!this.started)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GL20.glUseProgram(this.previousShader);
|
||||||
|
currentShader = this.previousShader;
|
||||||
|
|
||||||
|
this.started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String convertStreamToString(InputStream is) {
|
||||||
|
Scanner s = new Scanner(is).useDelimiter("\\A");
|
||||||
|
return s.hasNext() ? s.next() : "";
|
||||||
|
}
|
||||||
|
}
|
133
src/com/osufx/sunpy/ShaderProperty.java
Normal file
133
src/com/osufx/sunpy/ShaderProperty.java
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
package com.osufx.sunpy;
|
||||||
|
|
||||||
|
import org.lwjgl.BufferUtils;
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
|
public class ShaderProperty {
|
||||||
|
public String Name;
|
||||||
|
public int Location;
|
||||||
|
|
||||||
|
public Class Type;
|
||||||
|
public UniformType ActiveUniformType;
|
||||||
|
|
||||||
|
public Object Value;
|
||||||
|
|
||||||
|
public ShaderProperty(String Name, int Location, Class Type, UniformType ActiveUniformType) {
|
||||||
|
this.Name = Name;
|
||||||
|
this.Location = Location;
|
||||||
|
this.Type = Type;
|
||||||
|
this.ActiveUniformType = ActiveUniformType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set() {
|
||||||
|
if (Value == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (this.ActiveUniformType) {
|
||||||
|
case Bool:
|
||||||
|
GL20.glUniform1(this.Location, IntBuffer.wrap( new int[]{ (boolean)Value ? 1 : 0 } ));
|
||||||
|
break;
|
||||||
|
case Int:
|
||||||
|
GL20.glUniform1(this.Location, IntBuffer.wrap( new int[]{ (int)Value } ));
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
GL20.glUniform1(this.Location, FloatBuffer.wrap( new float[]{ (float)Value } ));
|
||||||
|
break;
|
||||||
|
case BoolVec2:
|
||||||
|
GL20.glUniform2(this.Location, IntBuffer.wrap( boolArrayToIntArray( (boolean[])Value ) ));
|
||||||
|
break;
|
||||||
|
case IntVec2:
|
||||||
|
GL20.glUniform2(this.Location, IntBuffer.wrap( (int[])Value ));
|
||||||
|
break;
|
||||||
|
case FloatVec2:
|
||||||
|
GL20.glUniform2(this.Location, FloatBuffer.wrap( (float[])Value ));
|
||||||
|
break;
|
||||||
|
case FloatMat2:
|
||||||
|
GL20.glUniformMatrix2(this.Location, false, FloatBuffer.wrap( (float[])Value ));
|
||||||
|
break;
|
||||||
|
case BoolVec3:
|
||||||
|
GL20.glUniform3(this.Location, IntBuffer.wrap( boolArrayToIntArray( (boolean[])Value ) ));
|
||||||
|
break;
|
||||||
|
case IntVec3:
|
||||||
|
GL20.glUniform3(this.Location, IntBuffer.wrap( (int[])Value ));
|
||||||
|
break;
|
||||||
|
case FloatVec3:
|
||||||
|
GL20.glUniform3(this.Location, FloatBuffer.wrap( (float[])Value ));
|
||||||
|
break;
|
||||||
|
case FloatMat3:
|
||||||
|
GL20.glUniformMatrix3(this.Location, false, FloatBuffer.wrap( (float[])Value ));
|
||||||
|
break;
|
||||||
|
case BoolVec4:
|
||||||
|
GL20.glUniform4(this.Location, IntBuffer.wrap( boolArrayToIntArray( (boolean[])Value ) ));
|
||||||
|
break;
|
||||||
|
case IntVec4:
|
||||||
|
GL20.glUniform4(this.Location, IntBuffer.wrap( (int[])Value ));
|
||||||
|
break;
|
||||||
|
case FloatVec4:
|
||||||
|
GL20.glUniform4(this.Location, FloatBuffer.wrap( (float[])Value ));
|
||||||
|
break;
|
||||||
|
case FloatMat4:
|
||||||
|
GL20.glUniformMatrix4(this.Location, false, FloatBuffer.wrap( (float[])Value ));
|
||||||
|
break;
|
||||||
|
case Sampler2D:
|
||||||
|
GL20.glUniform1(this.Location, BufferUtils.createIntBuffer(1).put((int) Value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class ConvertType(String type) {
|
||||||
|
switch (type) {
|
||||||
|
default:
|
||||||
|
//throw new Exception(String.format("Uniform type %s is not supported.", type));
|
||||||
|
System.out.println(String.format("Uniform type %s is not supported.", type));
|
||||||
|
return null;
|
||||||
|
case "Bool":
|
||||||
|
return Boolean.class;
|
||||||
|
case "Int":
|
||||||
|
return Integer.class;
|
||||||
|
case "Float":
|
||||||
|
return Float.class;
|
||||||
|
case "BoolVec2":
|
||||||
|
return boolean[].class;
|
||||||
|
case "IntVec2":
|
||||||
|
return int[].class;
|
||||||
|
case "FloatVec2":
|
||||||
|
return float[].class;
|
||||||
|
case "BoolVec3":
|
||||||
|
return boolean[].class;
|
||||||
|
case "IntVec3":
|
||||||
|
return int[].class;
|
||||||
|
case "FloatVec3":
|
||||||
|
return float[].class;
|
||||||
|
case "BoolVec4":
|
||||||
|
return boolean[].class;
|
||||||
|
case "IntVec4":
|
||||||
|
return int[].class;
|
||||||
|
case "FloatVec4":
|
||||||
|
return float[].class;
|
||||||
|
case "FloatMat2":
|
||||||
|
return float[].class;
|
||||||
|
case "FloatMat3":
|
||||||
|
return float[].class;
|
||||||
|
case "FloatMat4":
|
||||||
|
return float[].class;
|
||||||
|
case "Sampler2D":
|
||||||
|
case "SamplerCube":
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static Type ConvertType(int type) {
|
||||||
|
(UniformType)24;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public static int[] boolArrayToIntArray(boolean[] array) {
|
||||||
|
int[] value = new int[array.length];
|
||||||
|
for (int i = 0; i < array.length; i++)
|
||||||
|
value[i] = array[i] ? 1 : 0;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
39
src/com/osufx/sunpy/UniformType.java
Normal file
39
src/com/osufx/sunpy/UniformType.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package com.osufx.sunpy;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public enum UniformType {
|
||||||
|
Int(GL11.GL_INT),
|
||||||
|
Float(GL11.GL_FLOAT),
|
||||||
|
FloatVec2(GL20.GL_FLOAT_VEC2),
|
||||||
|
FloatVec3(GL20.GL_FLOAT_VEC3),
|
||||||
|
FloatVec4(GL20.GL_FLOAT_VEC4),
|
||||||
|
IntVec2(GL20.GL_INT_VEC2),
|
||||||
|
IntVec3(GL20.GL_INT_VEC3),
|
||||||
|
IntVec4(GL20.GL_INT_VEC4),
|
||||||
|
Bool(GL20.GL_BOOL),
|
||||||
|
BoolVec2(GL20.GL_BOOL_VEC2),
|
||||||
|
BoolVec3(GL20.GL_BOOL_VEC3),
|
||||||
|
BoolVec4(GL20.GL_BOOL_VEC4),
|
||||||
|
FloatMat2(GL20.GL_FLOAT_MAT2),
|
||||||
|
FloatMat3(GL20.GL_FLOAT_MAT3),
|
||||||
|
FloatMat4(GL20.GL_FLOAT_MAT4),
|
||||||
|
Sampler2D(GL20.GL_SAMPLER_2D),
|
||||||
|
SamplerCube(GL20.GL_SAMPLER_CUBE);
|
||||||
|
|
||||||
|
private final int glIndex;
|
||||||
|
|
||||||
|
public static HashMap<Integer, UniformType> map = new HashMap<>();
|
||||||
|
static {
|
||||||
|
for (UniformType v : UniformType.values()) {
|
||||||
|
map.put(v.glIndex, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UniformType(int glIndex) {
|
||||||
|
this.glIndex = glIndex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package itdelatrisu.opsu.render;
|
package itdelatrisu.opsu.render;
|
||||||
|
|
||||||
|
import com.osufx.sunpy.Shader;
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.beatmap.HitObject;
|
import itdelatrisu.opsu.beatmap.HitObject;
|
||||||
|
@ -248,7 +249,7 @@ public class CurveRenderState {
|
||||||
GL11.glTexParameteri(GL11.GL_TEXTURE_1D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_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);
|
GL11.glTexParameteri(GL11.GL_TEXTURE_1D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
|
||||||
|
|
||||||
GL20.glUseProgram(0);
|
GL20.glUseProgram(Shader.currentShader);
|
||||||
|
|
||||||
GL11.glMatrixMode(GL11.GL_PROJECTION);
|
GL11.glMatrixMode(GL11.GL_PROJECTION);
|
||||||
GL11.glPushMatrix();
|
GL11.glPushMatrix();
|
||||||
|
|
|
@ -307,7 +307,7 @@ public class Game extends ComplexOpsuState {
|
||||||
MUSICBAR_HOVER = new Color(12, 9, 10, 0.35f),
|
MUSICBAR_HOVER = new Color(12, 9, 10, 0.35f),
|
||||||
MUSICBAR_FILL = new Color(255, 255, 255, 0.75f);
|
MUSICBAR_FILL = new Color(255, 255, 255, 0.75f);
|
||||||
|
|
||||||
private final Cursor mirrorCursor;
|
private Cursor mirrorCursor;
|
||||||
private final MoveStoryboard moveStoryboardOverlay;
|
private final MoveStoryboard moveStoryboardOverlay;
|
||||||
private final StoryboardOverlay storyboardOverlay;
|
private final StoryboardOverlay storyboardOverlay;
|
||||||
private final OptionsOverlay optionsOverlay;
|
private final OptionsOverlay optionsOverlay;
|
||||||
|
@ -318,7 +318,7 @@ public class Game extends ComplexOpsuState {
|
||||||
|
|
||||||
public Game() {
|
public Game() {
|
||||||
super();
|
super();
|
||||||
mirrorCursor = new Cursor(true);
|
//mirrorCursor = new Cursor(true);
|
||||||
this.moveStoryboardOverlay = new MoveStoryboard();
|
this.moveStoryboardOverlay = new MoveStoryboard();
|
||||||
this.optionsOverlay = new OptionsOverlay(OptionGroups.storyboardOptions);
|
this.optionsOverlay = new OptionsOverlay(OptionGroups.storyboardOptions);
|
||||||
this.storyboardOverlay = new StoryboardOverlay(moveStoryboardOverlay, optionsOverlay, this);
|
this.storyboardOverlay = new StoryboardOverlay(moveStoryboardOverlay, optionsOverlay, this);
|
||||||
|
@ -1501,6 +1501,7 @@ public class Game extends ComplexOpsuState {
|
||||||
|
|
||||||
super.enter();
|
super.enter();
|
||||||
|
|
||||||
|
/*
|
||||||
File replaydir = new File("d:/Users/Robin/games/osu/osr-stuff-master/xi/");
|
File replaydir = new File("d:/Users/Robin/games/osu/osr-stuff-master/xi/");
|
||||||
if (!replaydir.exists()) {
|
if (!replaydir.exists()) {
|
||||||
bubNotifs.sendf(Colors.BUB_RED, "replay folder '%s' does not exist", replaydir.getAbsolutePath());
|
bubNotifs.sendf(Colors.BUB_RED, "replay folder '%s' does not exist", replaydir.getAbsolutePath());
|
||||||
|
@ -1577,7 +1578,7 @@ public class Game extends ComplexOpsuState {
|
||||||
replayidx++;
|
replayidx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
displayContainer.drawCursor = false;
|
displayContainer.drawCursor = false;*/
|
||||||
|
|
||||||
isInGame = true;
|
isInGame = true;
|
||||||
if (!skippedToCheckpoint) {
|
if (!skippedToCheckpoint) {
|
||||||
|
|
|
@ -18,18 +18,34 @@
|
||||||
|
|
||||||
package itdelatrisu.opsu.ui;
|
package itdelatrisu.opsu.ui;
|
||||||
|
|
||||||
|
import com.osufx.sunpy.Shader;
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
|
import itdelatrisu.opsu.render.Rendertarget;
|
||||||
import itdelatrisu.opsu.ui.animations.AnimationEquation;
|
import itdelatrisu.opsu.ui.animations.AnimationEquation;
|
||||||
|
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import org.lwjgl.BufferUtils;
|
||||||
|
import org.lwjgl.opengl.EXTFramebufferObject;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL13;
|
||||||
|
import org.lwjgl.opengl.GL14;
|
||||||
import org.newdawn.slick.*;
|
import org.newdawn.slick.*;
|
||||||
|
import org.newdawn.slick.opengl.Texture;
|
||||||
|
import org.newdawn.slick.opengl.TextureImpl;
|
||||||
|
|
||||||
import yugecin.opsudance.Dancer;
|
import yugecin.opsudance.Dancer;
|
||||||
|
import yugecin.opsudance.ReplayPlayback;
|
||||||
import yugecin.opsudance.skinning.SkinService;
|
import yugecin.opsudance.skinning.SkinService;
|
||||||
|
|
||||||
import static yugecin.opsudance.options.Options.*;
|
import static yugecin.opsudance.options.Options.*;
|
||||||
|
import static itdelatrisu.opsu.GameImage.CURSOR;
|
||||||
|
import static itdelatrisu.opsu.GameImage.CURSOR_MIDDLE;
|
||||||
|
import static itdelatrisu.opsu.GameImage.CURSOR_TRAIL;
|
||||||
import static yugecin.opsudance.core.InstanceContainer.*;
|
import static yugecin.opsudance.core.InstanceContainer.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,8 +71,7 @@ public class Cursor {
|
||||||
/** The time it takes for the cursor to scale, in milliseconds. */
|
/** The time it takes for the cursor to scale, in milliseconds. */
|
||||||
private static final float CURSOR_SCALE_TIME = 125;
|
private static final float CURSOR_SCALE_TIME = 125;
|
||||||
|
|
||||||
/** Stores all previous cursor locations to display a trail. */
|
private TrailList trail = new TrailList();
|
||||||
private LinkedList<Point> trail = new LinkedList<>();
|
|
||||||
|
|
||||||
private boolean newStyle;
|
private boolean newStyle;
|
||||||
|
|
||||||
|
@ -69,6 +84,10 @@ public class Cursor {
|
||||||
private boolean isMirrored;
|
private boolean isMirrored;
|
||||||
|
|
||||||
private Color filter;
|
private Color filter;
|
||||||
|
|
||||||
|
private Rendertarget fbo;
|
||||||
|
|
||||||
|
private Shader cursorTrailShader;
|
||||||
|
|
||||||
public Cursor() {
|
public Cursor() {
|
||||||
this(false);
|
this(false);
|
||||||
|
@ -77,6 +96,9 @@ public class Cursor {
|
||||||
public Cursor(boolean isMirrored) {
|
public Cursor(boolean isMirrored) {
|
||||||
resetLocations(0, 0);
|
resetLocations(0, 0);
|
||||||
this.isMirrored = isMirrored;
|
this.isMirrored = isMirrored;
|
||||||
|
this.lastPosition = new Point(width2, 0);
|
||||||
|
this.filter = new Color(255,255,255);
|
||||||
|
this.cursorTrailShader = new Shader("sh_Cursor.vertex", "sh_Texture.frag");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cursor(Color filter) {
|
public Cursor(Color filter) {
|
||||||
|
@ -89,6 +111,10 @@ public class Cursor {
|
||||||
* @param mousePressed whether or not the mouse button is pressed
|
* @param mousePressed whether or not the mouse button is pressed
|
||||||
*/
|
*/
|
||||||
public void draw(boolean mousePressed) {
|
public void draw(boolean mousePressed) {
|
||||||
|
if (fbo == null) {
|
||||||
|
this.fbo = Rendertarget.createRTTFramebuffer(width, height);
|
||||||
|
}
|
||||||
|
/*
|
||||||
if (OPTION_DISABLE_CURSOR.state) {
|
if (OPTION_DISABLE_CURSOR.state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -168,6 +194,78 @@ public class Cursor {
|
||||||
if (hasMiddle) {
|
if (hasMiddle) {
|
||||||
cursorMiddle.drawCentered(lastPosition.x, lastPosition.y, OPTION_DANCE_CURSOR_ONLY_COLOR_TRAIL.state ? Color.white : filter);
|
cursorMiddle.drawCentered(lastPosition.x, lastPosition.y, OPTION_DANCE_CURSOR_ONLY_COLOR_TRAIL.state ? Color.white : filter);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
final Image img = CURSOR_TRAIL.getImage();
|
||||||
|
final Texture txt = img.getTexture();
|
||||||
|
|
||||||
|
final float trailw2 = img.getWidth() * OPTION_CURSOR_SIZE.val / 100f / 2f;
|
||||||
|
final float trailh2 = img.getHeight() * OPTION_CURSOR_SIZE.val / 100f / 2f;
|
||||||
|
float txtw = txt.getWidth();
|
||||||
|
float txth = txt.getHeight();
|
||||||
|
|
||||||
|
/*
|
||||||
|
// stuff copied from CurveRenderState and stuff, I don't know what I'm doing
|
||||||
|
int oldFb = GL11.glGetInteger(EXTFramebufferObject.GL_FRAMEBUFFER_BINDING_EXT);
|
||||||
|
int oldTex = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
|
||||||
|
IntBuffer oldViewport = BufferUtils.createIntBuffer(16);
|
||||||
|
GL11.glGetInteger(GL11.GL_VIEWPORT, oldViewport);
|
||||||
|
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, fbo.getID());
|
||||||
|
GL11.glViewport(0, 0, fbo.width, fbo.height);
|
||||||
|
GL11.glClearColor(0f, 0f, 0f, 0f);
|
||||||
|
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
|
||||||
|
*/
|
||||||
|
//txt.bind();
|
||||||
|
Color.white.bind();
|
||||||
|
TextureImpl.unbind();
|
||||||
|
cursorTrailShader.Begin();
|
||||||
|
GL11.glBegin(GL11.GL_QUADS);
|
||||||
|
|
||||||
|
//GL11.glBindTexture(GL11.GL_TEXTURE_2D, );
|
||||||
|
//cursorTrailShader.Properties.set("m_Sampler", txt.getTextureID());
|
||||||
|
//cursorTrailShader.Properties.set("g_FadeClock", 0.4f);
|
||||||
|
float alpha = 0f;
|
||||||
|
float alphaIncrease = .4f / trail.size;
|
||||||
|
for (Trailpart p : trail) {
|
||||||
|
//alpha += alphaIncrease;
|
||||||
|
GL11.glColor4f(filter.r, filter.g, filter.b, alpha);
|
||||||
|
//GL11.glTexCoord2f(0f, 0f);
|
||||||
|
GL11.glVertex3f(p.x - trailw2, p.y - trailh2, 0f);
|
||||||
|
//GL11.glTexCoord2f(txtw, 0);
|
||||||
|
GL11.glVertex3f(p.x + trailw2, p.y - trailh2, 0f);
|
||||||
|
//GL11.glTexCoord2f(txtw, txth);
|
||||||
|
GL11.glVertex3f(p.x + trailw2, p.y + trailh2, 0f);
|
||||||
|
//GL11.glTexCoord2f(0f, txth);
|
||||||
|
GL11.glVertex3f(p.x - trailw2, p.y + trailh2, 0f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//GL11.glEnd();
|
||||||
|
GL11.glEnd();
|
||||||
|
cursorTrailShader.End();
|
||||||
|
|
||||||
|
/*
|
||||||
|
GL11.glBindTexture(GL11.GL_TEXTURE_2D, oldTex);
|
||||||
|
EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, oldFb);
|
||||||
|
GL11.glViewport(oldViewport.get(0), oldViewport.get(1), oldViewport.get(2), oldViewport.get(3));
|
||||||
|
|
||||||
|
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
|
||||||
|
//GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||||
|
//GL11.glDisable(GL11.GL_TEXTURE_1D);
|
||||||
|
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbo.getTextureID());
|
||||||
|
GL11.glBegin(GL11.GL_QUADS);
|
||||||
|
GL11.glColor4f(1f, 1f, 1f, 1f);
|
||||||
|
GL11.glTexCoord2f(1f, 1f);
|
||||||
|
GL11.glVertex2i(fbo.width, 0);
|
||||||
|
GL11.glTexCoord2f(0f, 1f);
|
||||||
|
GL11.glVertex2i(0, 0);
|
||||||
|
GL11.glTexCoord2f(0f, 0f);
|
||||||
|
GL11.glVertex2i(0, fbo.height);
|
||||||
|
GL11.glTexCoord2f(1f, 0f);
|
||||||
|
GL11.glVertex2i(fbo.width, fbo.height);
|
||||||
|
GL11.glEnd();
|
||||||
|
GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
*/
|
||||||
|
//CURSOR.getScaledImage(OPTION_CURSOR_SIZE.val / 100f).drawCentered(lastPosition.x, lastPosition.y, filter);
|
||||||
|
//CURSOR_MIDDLE.getScaledImage(OPTION_CURSOR_SIZE.val / 100f).drawCentered(lastPosition.x, lastPosition.y, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,34 +274,22 @@ public class Cursor {
|
||||||
* @param mouseY y coordinate to set position to
|
* @param mouseY y coordinate to set position to
|
||||||
*/
|
*/
|
||||||
public void setCursorPosition(int delta, int mouseX, int mouseY) {
|
public void setCursorPosition(int delta, int mouseX, int mouseY) {
|
||||||
// TODO: use an image buffer
|
nowtime = System.currentTimeMillis();
|
||||||
int removeCount = 0;
|
|
||||||
float FPSmod = Math.max(1000 / Math.max(delta, 1), 1) / 30f; // TODO
|
|
||||||
if (newStyle) {
|
|
||||||
// new style: add all points between cursor movements
|
|
||||||
if ((lastPosition.x == 0 && lastPosition.y == 0) || !addCursorPoints(lastPosition.x, lastPosition.y, mouseX, mouseY)) {
|
|
||||||
trail.add(new Point(mouseX, mouseY));
|
|
||||||
}
|
|
||||||
lastPosition.move(mouseX, mouseY);
|
|
||||||
|
|
||||||
removeCount = (int) (trail.size() / (6 * FPSmod)) + 1;
|
addCursorPoints(lastPosition.x, lastPosition.y, mouseX, mouseY);
|
||||||
} else {
|
lastPosition.move(mouseX, mouseY);
|
||||||
// old style: sample one point at a time
|
|
||||||
trail.add(new Point(mouseX, mouseY));
|
|
||||||
|
|
||||||
int max = (int) (10 * FPSmod);
|
int removecount = 0;
|
||||||
if (trail.size() > max)
|
TrailNode newfirst = trail.first;
|
||||||
removeCount = trail.size() - max;
|
while (newfirst != null && newfirst.value.time < nowtime - 175) {
|
||||||
|
newfirst = newfirst.next;
|
||||||
|
removecount++;
|
||||||
}
|
}
|
||||||
|
trail.first = newfirst;
|
||||||
int cursortraillength = OPTION_DANCE_CURSOR_TRAIL_OVERRIDE.val;
|
if (newfirst == null) {
|
||||||
if (cursortraillength > 20) {
|
trail.last = null;
|
||||||
removeCount = trail.size() - cursortraillength;
|
|
||||||
}
|
}
|
||||||
|
trail.size -= removecount;
|
||||||
// remove points from the lists
|
|
||||||
for (int i = 0; i < removeCount && !trail.isEmpty(); i++)
|
|
||||||
trail.remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -211,8 +297,8 @@ public class Cursor {
|
||||||
* @author http://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm#Java
|
* @author http://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm#Java
|
||||||
*/
|
*/
|
||||||
private boolean addCursorPoints(int x1, int y1, int x2, int y2) {
|
private boolean addCursorPoints(int x1, int y1, int x2, int y2) {
|
||||||
|
int size = trail.size;
|
||||||
// delta of exact value and rounded value of the dependent variable
|
// delta of exact value and rounded value of the dependent variable
|
||||||
boolean added = false;
|
|
||||||
int d = 0;
|
int d = 0;
|
||||||
int dy = Math.abs(y2 - y1);
|
int dy = Math.abs(y2 - y1);
|
||||||
int dx = Math.abs(x2 - x1);
|
int dx = Math.abs(x2 - x1);
|
||||||
|
@ -222,16 +308,11 @@ public class Cursor {
|
||||||
int ix = x1 < x2 ? 1 : -1; // increment direction
|
int ix = x1 < x2 ? 1 : -1; // increment direction
|
||||||
int iy = y1 < y2 ? 1 : -1;
|
int iy = y1 < y2 ? 1 : -1;
|
||||||
|
|
||||||
int k = 5; // sample size
|
|
||||||
if (dy <= dx) {
|
if (dy <= dx) {
|
||||||
for (int i = 0; ; i++) {
|
for (;;) {
|
||||||
if (i == k) {
|
|
||||||
trail.add(new Point(x1, y1));
|
|
||||||
added = true;
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
if (x1 == x2)
|
if (x1 == x2)
|
||||||
break;
|
break;
|
||||||
|
trail.add(new Trailpart(x1, y1));
|
||||||
x1 += ix;
|
x1 += ix;
|
||||||
d += dy2;
|
d += dy2;
|
||||||
if (d > dx) {
|
if (d > dx) {
|
||||||
|
@ -240,14 +321,10 @@ public class Cursor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; ; i++) {
|
for (;;) {
|
||||||
if (i == k) {
|
|
||||||
trail.add(new Point(x1, y1));
|
|
||||||
added = true;
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
if (y1 == y2)
|
if (y1 == y2)
|
||||||
break;
|
break;
|
||||||
|
trail.add(new Trailpart(x1, y1));
|
||||||
y1 += iy;
|
y1 += iy;
|
||||||
d += dx2;
|
d += dx2;
|
||||||
if (d > dy) {
|
if (d > dy) {
|
||||||
|
@ -256,7 +333,64 @@ public class Cursor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return added;
|
return trail.size != size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TrailList implements Iterable<Trailpart>
|
||||||
|
{
|
||||||
|
TrailNode first;
|
||||||
|
TrailNode last;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
public void add(Trailpart t)
|
||||||
|
{
|
||||||
|
if (last == null) {
|
||||||
|
last = first = new TrailNode(t);
|
||||||
|
} else {
|
||||||
|
TrailNode n = new TrailNode(t);
|
||||||
|
last.next = n;
|
||||||
|
last = n;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Trailpart> iterator()
|
||||||
|
{
|
||||||
|
return new Iterator<Trailpart>() {
|
||||||
|
TrailNode node = first;
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return node != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Trailpart next() {
|
||||||
|
Trailpart v = node.value;
|
||||||
|
node = node.next;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TrailNode
|
||||||
|
{
|
||||||
|
TrailNode next;
|
||||||
|
Trailpart value;
|
||||||
|
TrailNode(Trailpart t) {
|
||||||
|
value = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Trailpart {
|
||||||
|
int x, y;
|
||||||
|
long time;
|
||||||
|
Trailpart(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.time = nowtime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,11 +423,7 @@ public class Cursor {
|
||||||
* Resets all cursor location data.
|
* Resets all cursor location data.
|
||||||
*/
|
*/
|
||||||
public void resetLocations(int mouseX, int mouseY) {
|
public void resetLocations(int mouseX, int mouseY) {
|
||||||
trail.clear();
|
|
||||||
lastPosition = new Point(mouseX, mouseY);
|
|
||||||
for (int i = 0; i < 50; i++) {
|
|
||||||
trail.add(new Point(lastPosition));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class DisplayContainer implements ErrorDumpable, SkinChangedListener {
|
||||||
|
|
||||||
private long exitconfirmation;
|
private long exitconfirmation;
|
||||||
|
|
||||||
public final Cursor cursor;
|
public Cursor cursor;
|
||||||
public boolean drawCursor;
|
public boolean drawCursor;
|
||||||
|
|
||||||
private final List<ResolutionChangedListener> resolutionChangedListeners;
|
private final List<ResolutionChangedListener> resolutionChangedListeners;
|
||||||
|
@ -106,8 +106,6 @@ public class DisplayContainer implements ErrorDumpable, SkinChangedListener {
|
||||||
public DisplayContainer()
|
public DisplayContainer()
|
||||||
{
|
{
|
||||||
this.resolutionChangedListeners = new ArrayList<>();
|
this.resolutionChangedListeners = new ArrayList<>();
|
||||||
this.cursor = new Cursor();
|
|
||||||
drawCursor = true;
|
|
||||||
|
|
||||||
skinservice.addSkinChangedListener(this);
|
skinservice.addSkinChangedListener(this);
|
||||||
|
|
||||||
|
@ -271,6 +269,8 @@ public class DisplayContainer implements ErrorDumpable, SkinChangedListener {
|
||||||
glVersion = GL11.glGetString(GL11.GL_VERSION);
|
glVersion = GL11.glGetString(GL11.GL_VERSION);
|
||||||
glVendor = GL11.glGetString(GL11.GL_VENDOR);
|
glVendor = GL11.glGetString(GL11.GL_VENDOR);
|
||||||
GLHelper.hideNativeCursor();
|
GLHelper.hideNativeCursor();
|
||||||
|
this.cursor = new Cursor();
|
||||||
|
drawCursor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move this elsewhere
|
// TODO: move this elsewhere
|
||||||
|
|
|
@ -35,6 +35,7 @@ public class Entrypoint {
|
||||||
try {
|
try {
|
||||||
InstanceContainer.kickstart();
|
InstanceContainer.kickstart();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
JOptionPane.showMessageDialog(null, e.getMessage(), "Cannot start " + PROJECT_NAME, JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null, e.getMessage(), "Cannot start " + PROJECT_NAME, JOptionPane.ERROR_MESSAGE);
|
||||||
// TODO replace with errorhandler
|
// TODO replace with errorhandler
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user