我正在尝试使用java的LWJGL编写一个简单的程序。当程序运行时,我想在开头和任何时候按“' 1”时给我一个红色屏幕。如果我按下' 2'它假设给我一个黑色到白色的渐变屏幕。程序运行但是当我按下' 2'它给了我这个错误
线程中的异常" main" java.lang.IllegalArgumentException:剩余缓冲区元素的数量为0,必须至少为3686400.因为最多可以返回3686400个元素,所以无论实际返回的元素数是多少,都需要一个至少包含3686400个元素的缓冲区
at org.lwjgl.BufferChecks.throwBufferSizeException(BufferChecks.java:162)
at org.lwjgl.BufferChecks.checkBufferSize(BufferChecks.java:189)
at org.lwjgl.BufferChecks.checkBuffer(BufferChecks.java:230)
at org.lwjgl.opengl.GL11.glDrawPixels(GL11.java:1059)
at LWJGL.Lab1.render(Lab1.java:68)
at LWJGL.Game.gameLoop(Game.java:84)
at LWJGL.Game.<init>(Game.java:25)
at LWJGL.Lab1.<init>(Lab1.java:11)
at LWJGL.Lab1.main(Lab1.java:93)
我不确定ByteBuffer做错了做什么。这是我的代码。
package LWJGL;
import java.nio.ByteBuffer;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.util.*;
public class Lab1 extends Game
{
private ByteBuffer raster;
private int drawmode = 1;
private int x,y;
public void init()
{
raster= ByteBuffer.allocate(640*480*3);
raster.asFloatBuffer();
Display.setTitle("Tutorial 1: A simple moving rectangle");
// Setup OpenGL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glOrtho(0, 800, 600, 0, 1, -1);
glViewport(0, 0, Display.getWidth(), Display.getHeight());
//initialize the raster
for(int i =0; i< raster.capacity(); i++){
raster.put((byte) (((float)i)/(640*480*3)));
}
}
public void update(long elapsedTime)
{
if (Keyboard.isKeyDown(Keyboard.KEY_1))
drawmode = 1;
if (Keyboard.isKeyDown(Keyboard.KEY_2))
drawmode =2;
}
public void render()
{
// Render to the screen here
glClearColor(1,0,0,1); // Set the clear color
// Clear the screen to the clear color (i.e. if the clear color
// is red, the screen turns red);
glClear(GL_COLOR_BUFFER_BIT);
if (drawmode == 2) {
// Save the old state so that you can set it back after you draw
//GLint oldmatrixmode;
boolean depthWasEnabled = glIsEnabled(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
//glGetIntegerv(GL_MATRIX_MODE,oldmatrixmode);
glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity();
glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();
// Draw the array of pixels (This is where you draw the values
// you have stored in the array 'raster')
glRasterPos2f(-1,-1);
GL11.glDrawPixels(640,480,GL_RGB,GL_FLOAT,raster);
//Set the state back to what it was
glPopMatrix();
glMatrixMode(GL_MODELVIEW); glPopMatrix();
//glMatrixMode(oldmatrixmode);
if (depthWasEnabled)
glEnable(GL_DEPTH_TEST);
}
glFlush();
}
public void resized()
{
// We reset the viewport here.
glViewport(0, 0, Display.getWidth(), Display.getHeight());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
public static void main(String[] args)
{
new Lab1();
}
}
抽象类游戏不是问题。
答案 0 :(得分:2)
asFloatBuffer (...)
本身什么都不做。它返回另一个缓冲区,它引用与原始缓冲区相同的数据,但使用不同的表示形式。如果您不使用返回值,则没有理由调用它。
您的ByteBuffer
的大小应该是存储640 * 480 * 3浮点组件的1/4。
GLfloat
在OpenGL中必须是32位 - &gt; 4字节。
ByteBuffer.put (...)
会增加缓冲区的“当前”位置。这是LWJGL在将数据写入缓冲区时使用的位置。
flip
缓冲区,那么您的开始位置就是缓冲区的结尾。 LWJGL会立即溢出你的缓冲区。以下是您问题的一种可能解决方案,不需要调用raster.flip (...)
(因为rasterAsFloats
将其位置与raster
分开存储):
public void init()
{
raster = ByteBuffer.allocate (640*480*4*3);
FloatBuffer rasterAsFloats = raster.asFloatBuffer ();
Display.setTitle("Tutorial 1: A simple moving rectangle");
// Setup OpenGL
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glOrtho(0, 800, 600, 0, 1, -1);
glViewport(0, 0, Display.getWidth(), Display.getHeight());
//initialize the raster
for(int i =0; i< rasterAsFloats.capacity(); i++){
rasterAsFloats.put ((((float)i)/(640*480*3)));
}
}
我从未说过代码实际上会产生你想要的渐变。只是它会解决你的崩溃问题。以下是可能生成渐变的一些代码,它应该足以让您至少开始:
for (int i = 0; i < rasterAsFloats.capacity (); i+=3) {
float luminance = ((float)(i/(640 * 3))/480.0f);
rasterAsFloats.put (luminance); // R
rasterAsFloats.put (luminance); // G
rasterAsFloats.put (luminance); // B
}