我的LWJGL程序存在严重问题。
如果我设置了文本的一种颜色,背景的颜色也会改变。
我想我知道为什么,我只是将所有的绘画事物放在一个无限循环中,也许这就是原因。
你能帮助我吗?我是否纠正了问题的原因?如果是,我该如何解决?如果没有,你怎么看,问题是什么?
这是我的代码:
主要班级:
<!-- language: lang-java -->
public class DoomMain {
public static final int WIDTH = 640;
public static final int HEIGHT = 480;
public static final int SCALE = 1;
private static State state;
public DoomMain() {
try {
Display.setDisplayMode(new DisplayMode(WIDTH*SCALE,HEIGHT*SCALE));
Display.setTitle("Tomco - Doom");
Display.create();
} catch(LWJGLException e) {
e.printStackTrace();
}
while(!Display.isCloseRequested()) {
state = State.MENU;
switch(state) {
case INTRO:
new Intro();
break;
case MENU:
new MainMenu();
break;
case CREDITS:
break;
case GAME:
break;
default:
break;
}
Display.update();
Display.sync(60);
}
Display.destroy();
}
public static void main(String[] args) {
new DoomMain();
}
}
MainMenu课程:
<!-- language: lang-java -->
public class MainMenu {
private Texture background;
private TrueTypeFont doomfont;
private boolean ana = false;
public MainMenu() {
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f,0.0f,0.0f,0.0f);
glEnable(GL11.GL_BLEND);
glBlendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE_MINUS_SRC_ALPHA);
glViewport(0,0,DoomMain.WIDTH,DoomMain.HEIGHT);
glMatrixMode(GL11.GL_MODELVIEW);
glMatrixMode(GL11.GL_PROJECTION);
glLoadIdentity();
glOrtho(0,DoomMain.WIDTH,DoomMain.HEIGHT,0,1,-1);
glMatrixMode(GL11.GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
drawBackground();
drawText();
glDisable(GL_TEXTURE_2D);
}
private void drawBackground() {
try {
background = TextureLoader.getTexture("PNG",new FileInputStream(new File("res/textures/mainmenu/doom_00340461.png")));
} catch (FileNotFoundException e) {
e.printStackTrace();
Display.destroy();
} catch (IOException e) {
e.printStackTrace();
Display.destroy();
}
glBegin(GL_QUADS);
{
glTexCoord2f(0,0);
glVertex2f(0,0);
glTexCoord2f(1,0);
glVertex2f(background.getTextureWidth(),0);
glTexCoord2f(1,1);
glVertex2f(background.getTextureWidth(),background.getTextureHeight());
glTexCoord2f(0,1);
glVertex2f(0,background.getTextureHeight());
}
glEnd();
}
private void drawText() {
Color.white.bind();
try {
InputStream inputStream = ResourceLoader.getResourceAsStream("res/fonts/DooM.ttf");
Font awtFont = Font.createFont(Font.TRUETYPE_FONT,inputStream);
awtFont = awtFont.deriveFont(24f);
doomfont = new TrueTypeFont(awtFont,ana);
} catch(Exception e) {
e.printStackTrace();
}
doomfont.drawString(200,100,"Start new game",Color.red);
}
}
答案 0 :(得分:2)
默认情况下,纹理将乘以当前颜色。作为状态机,每当您最后设置它时,“当前颜色”。在你的情况下,当你画文字;再次进入循环时,纹理使用相同的颜色。
为了简化问题,您可以将整个drawText例程简化为仅设置颜色:
LOOP:
a) draw background
b) set color
结果:...设定颜色;画背景......
glClear函数清除已经绘制的缓冲区,但不清除接下来要使用的颜色。
作为解决方案,您可以在绘制纹理之前显式更改颜色。 glColor3f(1.0f,1.0f,1.0f)将按原样生成纹理,任何其他值都可用作滤色器(就像现在一样)。
另一种解决方案是使用glTexEnv更改纹理绘制行为。假设纹理是GL_RGBA,则调用glTexEnv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE)。链接页面包含一个具有不同设置及其效果的表格。
答案 1 :(得分:1)
首先如果全部:Color.white.bind()
函数中的drawText()
调用可能会影响背景。
这是一个快速而又脏的示例,说明如何只加载一次数据。我已将数据加载到loadData()
函数。在打开屏幕后创建DoomMain
类,在主循环之前调用loadData()并使用menu.draw()
调用绘图。
理想情况下,您首先会在一个位置加载所需的所有资源,然后在初始化时将对象传递给DoomMain
。您可能也想在其他地方使用该纹理和字体..并且您不想多次加载它。
public DoomMain()
{
// Open screen here since we need a context to make textures etc
...
// Make objects for your different parts
MainMenu menu = MainMenu();
menu.loadData(); // <- Loads the texture and font
while(!Display.isCloseRequested())
{
state = State.MENU;
switch(state) {
...
case MENU:
menu.draw();
break;
...
}
Display.update();
Display.sync(60);
}
Display.destroy();
}
的MainMenu
public class MainMenu
{
private Texture background;
private TrueTypeFont doomfont;
private boolean ana = false;
public MainMenu() { }
public void loadData()
{
// Load the background texture
try {
background = TextureLoader.getTexture("PNG",new FileInputStream(new File("res/textures/mainmenu/doom_00340461.png")));
} catch (FileNotFoundException e) {
e.printStackTrace();
Display.destroy();
} catch (IOException e) {
e.printStackTrace();
Display.destroy();
}
// Load and initialize the font here
try {
InputStream inputStream = ResourceLoader.getResourceAsStream("res/fonts/DooM.ttf");
Font awtFont = Font.createFont(Font.TRUETYPE_FONT,inputStream);
awtFont = awtFont.deriveFont(24f);
doomfont = new TrueTypeFont(awtFont,ana);
} catch(Exception e) {
e.printStackTrace();
}
}
public void draw()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f,0.0f,0.0f,0.0f);
glEnable(GL11.GL_BLEND);
glBlendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE_MINUS_SRC_ALPHA);
glViewport(0,0,DoomMain.WIDTH,DoomMain.HEIGHT);
glMatrixMode(GL11.GL_MODELVIEW);
glMatrixMode(GL11.GL_PROJECTION);
glLoadIdentity();
glOrtho(0,DoomMain.WIDTH,DoomMain.HEIGHT,0,1,-1);
glMatrixMode(GL11.GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
drawBackground();
drawText();
glDisable(GL_TEXTURE_2D);
}
private void drawBackground()
{
... bind background texture
... draw your quad
}
private void drawText()
{
doomfont.drawString(....);
}
}