我正在用opengl在画布上渲染模型,因此使用while循环,并在一个线程下运行它,以免干扰主线程。我也有一个文本字段,我想在其中写一些文本。文本字段将重点放在我的动作上并接受输入,但是当在画布上悬停时,文本字段将进行对焦,但是我无法在其上写一些东西。这可能是由于while循环造成的,但我不知道该如何克服。我希望用户界面保持响应状态。
这是我的代码:
import java.awt.Canvas;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JTextField;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.PixelFormat;
public final class Loader extends JFrame {
public final int FPS = 120; // better cause of animations
public static Loader loader;
public Canvas canvas;
private Viewport viewport;
private JTextField textField;
private Loader() {
setTitle("Test");
setResizable(true);
setSize(320, 285);
setLocationRelativeTo(null);
getContentPane().setLayout(null);
setVisible(true);
canvas = new Canvas();
getContentPane().add(canvas);
canvas.setBounds(10, 24, 280, 163);
textField = new JTextField();
textField.setColumns(10);
textField.setBounds(91, 193, 116, 22);
getContentPane().add(textField);
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
// Initialize the frame
loader = new Loader();
new Thread(new Runnable() {
@Override
public void run() {
try {
// render the model
loader.render();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private static void init(Canvas canvas) throws Exception {
Display.setParent(canvas);
try {
Display.create(new PixelFormat(8, 24, 8, 8));
} catch (Exception ex) {
Display.create(new PixelFormat(8, 24, 8, 0));
}
Display.makeCurrent();
Display.setVSyncEnabled(false);
Display.setSwapInterval(0);
}
private void render() throws Exception {
init(canvas);
loader.viewport = new Viewport(canvas);
long[] timerCache = new long[10];
long timerCur = 0L;
long timerDst = 0L;
long timerLast = 0L;
long timerRate = 1000000L * 1000L / FPS;
int timerCacheIndex = 0;
int timerCacheSize = 0;
boolean minSleep = Runtime.getRuntime().availableProcessors() <= 1;
long[] clockCache = new long[32];
int clockIndex = 0;
int fps = 0;
while (isVisible()) {
long clock = System.nanoTime();
long lastClock = clockCache[clockIndex];
clockCache[clockIndex] = clock;
if (++clockIndex == 32)
clockIndex = 0;
if (lastClock != 0L && clock > lastClock) {
fps = (int) (1000000L * 1000L * 32L / (clock - lastClock));
}
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glClearColor(.5f, .6f, .9f, 1f);
loader.viewport.render();
if (minSleep)
try {
Thread.sleep(1L);
} catch (Exception ex) {
}
timerCache[timerCacheIndex++] = System.nanoTime();
if (timerCacheSize < timerCacheIndex)
timerCacheSize = timerCacheIndex;
if (timerCacheIndex == 10)
timerCacheIndex = 0;
long time = 0L;
for (int i = 0; i != timerCacheSize; time += timerCache[i++])
;
time /= (long) timerCacheSize;
if (timerCacheSize == 1)
timerLast = time;
timerCur += time - timerLast;
timerLast = time;
timerDst += timerRate;
if (timerDst > timerCur) {
long sleep = timerDst - timerCur;
try {
Thread.sleep(sleep / 1000000L, (int) (sleep % 1000000L));
} catch (Exception ex) {
}
timerCur = timerDst;
for (int i = 0; i != timerCacheSize; ++i)
timerCache[i] += sleep;
timerLast += sleep;
}
}
}
}
此gif可能有助于了解其当前外观。 https://gyazo.com/e6950fd8dd01306c704857e94f214f93.gif
我看不到这里的错误,我已经在render方法中使用了一个线程。
编辑:
Viewport.java
public Viewport(Canvas canvas) throws LWJGLException {
this.canvas = canvas;
this.scale = 1.0F;
this.pitch = 180.0F;
this.yaw = 0.0F;
this.roll = 0.0F;
}
public void render() {
try {
Dimension size = canvas.getSize();
if (models != null && size.width > 0 && size.height > 0) {
if (width != size.width || height != size.height) {
width = size.width;
height = size.height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float c = (float) Math.sqrt((double) (width * width) + (double) (height * height));
glOrtho(0.0F, (float) width, 0.0F, (float) height, -c, c);
glMatrixMode(GL_MODELVIEW);
}
if (Mouse.isButtonDown(0) && !Mouse.isButtonDown(1)) {
yaw -= (float) Mouse.getDX() / 2;
pitch -= (float) Mouse.getDY() / 2;
}
if (Mouse.isButtonDown(0) && Mouse.isButtonDown(1)) {
offset_z += (float) Mouse.getDY();
}
float wheel = (float) Mouse.getDWheel() / 1800.0F;
if (wheel > 1.0F)
wheel = 1.0F;
else if (wheel < -1.0F)
wheel = -1.0F;
scale += scale * wheel;
if (scale < 0.01F)
scale = 0.01F;
for (Model3D model : models) {
float x = (float) width / 2.0F;
float y = ((float) -((100.0F * (scale))) + offset_z) + (float) (height - model.height()) / 2.0F;
float z = 0.0F;
model.render(model, x, y, z, pitch, yaw, roll, scale, scale, scale);
}
Display.update();
}
} catch (Throwable t) {
}
}
答案 0 :(得分:-1)
代替:
new Thread(new Runnable() {
@Override
public void run() {
try {
// render the model
loader.render();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
也许是:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
// render the model
loader.render();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
它将在AWT调度线程上运行,也许问题会消失。摆动不是线程安全的,有时会使生活变得艰难。
答案 1 :(得分:-1)
您可以尝试在requestFocus()
类的render()
方法的末尾添加Loader
并报告发生的情况吗?