Java:如何使用LWJGL缩放2D图形以适应不同的分辨率
我目前正在为我正在制作的游戏引擎学习LWJGL(2.9.3)库。到目前为止,引擎中的一切都运转良好,除了一件事:不同的分辨率。我开始了一个单独的项目来保持事情的整洁,只是为了看看我是否错过了一些明显的东西,但这没有帮助 我的代码基本上只是在左上角附近画了一个红色的方块,这样我就可以确保缩放确实有效。当前,如果分辨率更改为大于监视器的分辨率,则其工作正常。但是,如果分辨率更改为高于监视器的分辨率,则块会更改大小并移动。我尝试过制作变量来改变相对于分辨率的缩放比例,我尝试过玩glOrtho,我尝试过玩glMatrixMode。似乎什么都没用。我会把我的代码放在下面,看看你们这些可爱的人能不能弄清楚到底发生了什么 主要类别:Java:如何使用LWJGL缩放2D图形以适应不同的分辨率,java,opengl,2d,lwjgl,scaling,Java,Opengl,2d,Lwjgl,Scaling,我目前正在为我正在制作的游戏引擎学习LWJGL(2.9.3)库。到目前为止,引擎中的一切都运转良好,除了一件事:不同的分辨率。我开始了一个单独的项目来保持事情的整洁,只是为了看看我是否错过了一些明显的东西,但这没有帮助 我的代码基本上只是在左上角附近画了一个红色的方块,这样我就可以确保缩放确实有效。当前,如果分辨率更改为大于监视器的分辨率,则其工作正常。但是,如果分辨率更改为高于监视器的分辨率,则块会更改大小并移动。我尝试过制作变量来改变相对于分辨率的缩放比例,我尝试过玩glOrtho,我尝试过
import static helperPackage.Artist.*;
public class Test {
// Everything will be rendered to a 1920 x 1080 display
public final int windowWidth = 1920;
public final int windowHeight = 1080;
// These are the current widths and heights that are changed
public static int cWindowWidth = 1920;
public static int cWindowHeight = 1080;
// Everything is full screen and VSync enabled
public boolean isFullscreen = true;
public boolean enableVSync = true;
// Scale variables (I tried using these and they only made it worse)
public float scaleX;
public float scaleY;
public Test()
{
setScales();
beginSession(windowWidth, windowHeight, isFullscreen, enableVSync);
while(!Display.isCloseRequested())
{
/*
* Code to draw a poorly made house
DrawQuad( 200 * scaleX, 200 * scaleY, 300 * scaleX, 200 * scaleY, 255, 0, 0);
DrawQuad( 325 * scaleX, 310 * scaleY, 50 * scaleX, 90 * scaleY, 115, 60, 0);
DrawQuad( 240 * scaleX, 310 * scaleY, 50 * scaleX, 40 * scaleY, 175, 220, 255);
DrawQuad( 410 * scaleX, 310 * scaleY, 50 * scaleX, 40 * scaleY, 175, 220, 255);
DrawQuad( 240 * scaleX, 225 * scaleY, 50 * scaleX, 40 * scaleY, 175, 220, 255);
DrawQuad( 410 * scaleX, 225 * scaleY, 50 * scaleX, 40 * scaleY, 175, 220, 255);
DrawQuad( 325 * scaleX, 225 * scaleY, 50 * scaleX, 40 * scaleY, 175, 220, 255);
DrawTriangle(100 * scaleX, 200 * scaleY, 600 * scaleX, 200 * scaleY, 350 * scaleX, 100 * scaleY, 115, 60, 0);
*/
// The quad used for testing
DrawQuad( 200, 200, 300, 200, 255, 0, 0);
// The code to change resolutions while the application is running
while (Keyboard.next())
{
if (Keyboard.getEventKeyState())
{
if (Keyboard.getEventKey() == Keyboard.KEY_1)
{
cWindowWidth = 1920;
cWindowHeight = 1080;
setScales();
updateDisplayMode(cWindowWidth, cWindowHeight, true);
}
else if (Keyboard.getEventKey() == Keyboard.KEY_2)
{
cWindowWidth = 800;
cWindowHeight = 600;
setScales();
updateDisplayMode(cWindowWidth, cWindowHeight, true);
}
else if (Keyboard.getEventKey() == Keyboard.KEY_3)
{
cWindowWidth = 640;
cWindowHeight = 480;
setScales();
updateDisplayMode(cWindowWidth, cWindowHeight, true);
}
else if (Keyboard.getEventKey() == Keyboard.KEY_4)
{
cWindowWidth = 4800;
cWindowHeight = 2700;
setScales();
updateDisplayMode(cWindowWidth, cWindowHeight, true);
}
}
}
Display.update();
Display.sync(60);
}
Display.destroy();
}
public static void main(String[] args)
{
new Test();
}
// Sets the scale variables
private void setScales()
{
scaleX = cWindowWidth / windowWidth;
scaleY = cWindowHeight / windowHeight;
}
}
艺术家班:
package helperPackage;
public class Artist {
public static void beginSession(int windowW, int windowH, boolean isFS, boolean isVS)
{
// Sets the Title of the application
Display.setTitle("LWJGL Tests");
try
{
// Sets the default resolution and full screen
updateDisplayMode(windowW, windowH, isFS);
// Enables VSync
Display.setVSyncEnabled(isVS);
// Sets the icons in the window and the task bar
Display.setIcon(new ByteBuffer[]
{
new ImageIOImageData().imageToByteBuffer(ImageIO.read(new File("src/resources/LOGOx32.png")), false, false, null),
new ImageIOImageData().imageToByteBuffer(ImageIO.read(new File("src/resources/LOGOx16.png")), false, false, null)
}
);
// Creates the display with Anti Aliasing
Display.create(new PixelFormat(0, 24, 8, 4));
}
catch (Exception e) {
e.printStackTrace();
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0D, 1920.0D, 1080.0D, 0.0D, 1.0D, -1.0D);
glMatrixMode(GL_MODELVIEW);
}
public static void updateDisplayMode(int width, int height, boolean fullscreen)
{
// Exits method if current DisplayMode is the target DisplayMode
if ((Display.getDisplayMode().getWidth() == width) && (Display.getDisplayMode().getHeight() == height) && (Display.isFullscreen() == fullscreen))
{
return;
}
// Try/Catch to handle errors
try
{
// Initializes the target DisplayMode
DisplayMode targetDisplayMode = null;
// Lowers the target dimensions to dimensions within range to prevent crashing
if (width > Display.getDesktopDisplayMode().getWidth())
{
width = Display.getDesktopDisplayMode().getWidth();
}
if (height > Display.getDesktopDisplayMode().getHeight())
{
height = Display.getDesktopDisplayMode().getHeight();
}
// Adjusts frequency and bits per pixel if the target is to be full screen
if (fullscreen)
{
// Initializes an array of compatible DisplayModes
DisplayMode[] modes = Display.getAvailableDisplayModes();
// Initializes a variable for the refresh rate of the monitor
int freq = 0;
// Creates a variable for temporary use in the loop
DisplayMode current;
// Sorts through all compatible DisplayModes
for (int i=0; i < modes.length; i++)
{
// Sets current to the DisplayMode being tested in the loop
current = modes[i];
// Checks to see if the temporary DisplayMode has the same dimensions as the target DisplayMode
if ((current.getWidth() == width) && (current.getHeight() == height))
{
// Tries to find a compatible refresh rate
if ((targetDisplayMode == null) || (current.getFrequency() >= freq))
{
// Tries to find a compatible bits per pixel
if ((targetDisplayMode == null) || (current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel()))
{
targetDisplayMode = current;
freq = targetDisplayMode.getFrequency();
}
}
// If bits per pixel and frequency match the display values
// it breaks the loop to set the DisplayMode
if ((current.getBitsPerPixel() == Display.getDesktopDisplayMode().getBitsPerPixel()) && (current.getFrequency() == Display.getDesktopDisplayMode().getFrequency()))
{
targetDisplayMode = current;
break;
}
}
}
}
// If the target is not full screen
else
{
targetDisplayMode = new DisplayMode(width, height);
}
// Prevents switching to an unsupported DisplayMode
if (targetDisplayMode == null) {
System.out.println("Failed to find value mode: " + width + "x" + height + " fs=" + fullscreen);
return;
}
// Sets the DisplayMode
Display.setDisplayMode(targetDisplayMode);
Display.setFullscreen(fullscreen);
}
// Catches any exceptions
catch (LWJGLException e)
{
System.out.println("Unable to setup mode " + width + "x" + height + " fullscreen=" + fullscreen + e);
}
}
public static void DrawQuad(float x, float y, float width, float height, float red, float green, float blue)
{
glBegin(GL_QUADS);
glColor3f(red / 255, green / 255, blue / 255);
glVertex2f(x, y);
glVertex2f(x + width, y);
glVertex2f(x + width, y + height);
glVertex2f(x, y + height);
glEnd();
}
}
package-helperPackage;
公共级艺术家{
公共静态void开始会话(int windowW、int windowH、布尔ISF、布尔ISV)
{
//设置应用程序的标题
Display.setTitle(“LWJGL测试”);
尝试
{
//设置默认分辨率和全屏显示
更新显示模式(windowW、windowH、isFS);
//启用VSync
Display.setVSyncEnabled(ISV);
//设置窗口和任务栏中的图标
Display.setIcon(新的ByteBuffer[]
{
新建ImageIOImageData().imageToByteBuffer(ImageIO.read(新文件(“src/resources/LOGOx32.png”)),false,false,null,
新建ImageIOImageData().imageToByteBuffer(ImageIO.read(新文件(“src/resources/LOGOx16.png”)),false、false、null
}
);
//使用抗锯齿创建显示
创建(新的像素格式(0,24,8,4));
}
捕获(例外e){
e、 printStackTrace();
}
glMatrixMode(GL_投影);
glLoadIdentity();
格洛托(0.0D,1920.0D,1080.0D,0.0D,1.0D,-1.0D);
glMatrixMode(GLU模型视图);
}
公共静态void updateDisplayMode(整数宽度、整数高度、布尔全屏)
{
//如果当前显示模式是目标显示模式,则退出方法
如果((Display.getDisplayMode().getWidth()==width)&&(Display.getDisplayMode().getHeight()==height)&&(Display.isFullscreen()==fullscreen))
{
返回;
}
//尝试/捕获以处理错误
尝试
{
//初始化目标显示模式
DisplayMode targetDisplayMode=null;
//将目标尺寸降低到范围内的尺寸,以防止碰撞
如果(宽度>显示.getDesktopDisplayMode().getWidth())
{
宽度=Display.getDesktopDisplayMode().getWidth();
}
如果(高度>显示.getDesktopDisplayMode().getHeight())
{
高度=显示。getDesktopDisplayMode().getHeight();
}
//如果目标是全屏显示,则调整频率和每像素位
如果(全屏)
{
//初始化兼容显示模式的数组
DisplayMode[]modes=Display.getAvailableDisplayModes();
//初始化监视器刷新率的变量
intfreq=0;
//创建用于在循环中临时使用的变量
显示模式电流;
//通过所有兼容的显示模式进行排序
对于(int i=0;i=freq))
{
//尝试查找每个像素的兼容位
if((targetDisplayMode==null)| |(current.getBitsPerPixel()>targetDisplayMode.getBitsPerPixel())
{
targetDisplayMode=当前;
freq=targetDisplayMode.getFrequency();
}
}
//如果每像素位和频率与显示值匹配
//它会中断循环以设置显示模式
如果((当前.getBitsPerPixel()==Display.getDesktopDisplayMode().getBitsPerPixel())&&(当前.getFrequency()==Display.getDesktopDisplayMode().getFrequency())