📄 glart_9_timing.java
字号:
*/
private void cleanup() {
Display.destroy();
}
//=====================================================
// Time functions
//=====================================================
public static long ticksPerSecond = 0; // used to calculate time
/**
* Returns the current time in seconds from the LWJGL high-precision
* timer. This function can be used to measure relative time ie.
* the time elapsed between two events, not an absolute time-of-day.
*
* Calls the LWJGL function Sys.getTime() to get the number of
* cpu "ticks". Divides this by the ticks-per-second to get the
* current time in seconds.
*/
public static double getTimeInSeconds()
{
if (ticksPerSecond == 0) { // initialize ticksPerSecond
ticksPerSecond = Sys.getTimerResolution();
}
return (((double)Sys.getTime())/(double)ticksPerSecond);
}
/**
* Convenience function returns time in milliseconds. Calls
* getTimeInSeconds().
*/
public static double getTimeInMillis()
{
return (double) (getTimeInSeconds() * 1000.0);
}
/**
* Given time in seconds, returns minutes:seconds formatted string.
*/
public String formatTime(double seconds) {
int secs = (int)(seconds % 60);
String strSecs = (secs < 10)? "0" + secs : "" + secs;
return "" + ((int)(seconds/60f)) + ":" + strSecs;
}
//=====================================================
// Texture functions
//=====================================================
/**
* Create a texture from the given image.
*/
public static int makeTexture(GLImage textureImg)
{
if ( textureImg == null ) {
return 0;
}
else {
return makeTexture(textureImg.pixelBuffer, textureImg.w, textureImg.h);
}
}
/**
* Create a texture from the given pixels in RGBA format. Set the texture
* to repeat in both directions and use LINEAR for magnification.
* @return the texture handle
*/
public static int makeTexture(ByteBuffer pixels, int w, int h)
{
// get a new empty texture
int textureHandle = allocateTexture();
// 'select' the new texture by it's handle
GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle);
// set texture parameters:
// how to wrap texture
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
// how to scale up texture
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); //GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); //GL11.GL_NEAREST);
// Create the texture from pixels
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, // type of texture we're creating
0, // level-of-detail: use 0
GL11.GL_RGBA, // texture pixel format
w, h, // width and height of texture image (powers of 2)
0, // widtt of the border (either 0 or 1, use 0)
GL11.GL_RGBA, // image pixel format
GL11.GL_UNSIGNED_BYTE, // image pixel data type
pixels // image pixel data
);
return textureHandle;
}
/**
* Build "Mipmap" for currently selected texture. Builds different
* versions of the texture image at lower levels of detail, so texture
* can scale down gracefully at longer distances.
*
* @param textureImg the texture image
* @return error code of buildMipMap call
*/
public static int makeTextureMipMap(GLImage textureImg)
{
int ret = GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, 4, textureImg.w,
textureImg.h, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, textureImg.getPixelsRGBA());
if (ret != 0) {
System.out.println("GLApp.makeTextureMipMap(): Error occured while building mip map, ret=" + ret);
}
//Assign the mip map levels and texture info
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_NEAREST);
GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
return ret;
}
/**
* Allocate a texture (glGenTextures) and return the handle to it.
*/
public static int allocateTexture()
{
IntBuffer textureHandle = allocInts(1);
GL11.glGenTextures(textureHandle);
return textureHandle.get(0);
}
public static final int SIZE_INT = 4;
public static IntBuffer allocInts(int howmany) {
return ByteBuffer.allocateDirect(howmany * SIZE_INT).order(ByteOrder.nativeOrder()).asIntBuffer();
}
//========================================================================
// Functions to build a character set and draw text strings.
//
// Example:
// buildFont("Font_tahoma.png");
// ...
// glPrint(100, 100, 0, "Here's some text");
// ...
// destroyFont(); // cleanup
//========================================================================
/**
* Build a character set from the given texture image.
*
* @param charSetImage texture image containing 256 characters in a 16x16 grid
* @param fontWidth how many pixels to allow per character on screen
*
* @see destroyFont()
*/
public void buildFont(String charSetImage, int fontWidth)
{
// make texture from image
GLImage textureImg = new GLImage(charSetImage);
fontTextureHandle = makeTexture(textureImg);
// build character set as call list of 256 textured quads
buildFont(fontTextureHandle, fontWidth);
}
/**
* Build the character set display list from the given texture. Creates
* one quad for each character, with one letter textured onto each quad.
* Assumes the texture is a 256x256 image containing every
* character of the charset arranged in a 16x16 grid. Each character
* is 16x16 pixels. Call destroyFont() to release the display list memory.
*
* Should be in ORTHO (2D) mode to render text (see setOrtho()).
*
* Special thanks to NeHe and Giuseppe D'Agata for the "2D Texture Font"
* tutorial (http://nehe.gamedev.net).
*
* @param charSetImage texture image containing 256 characters in a 16x16 grid
* @param fontWidth how many pixels to allow per character on screen
*
* @see destroyFont()
*/
public void buildFont(int fontTxtrHandle, int fontWidth)
{
float cx, cy;
fontListBase = GL11.glGenLists(256); // Creating 256 Display Lists
for (int i = 0; i < 256; i++) {
cx = (float) (i % 16) / 16f; // X Texture Coord Of Character (0 - 1.0)
cy = (float) (i / 16) / 16f; // Y Texture Coord Of Character (0 - 1.0)
GL11.glNewList(fontListBase + i, GL11.GL_COMPILE); // Start Building A List
GL11.glBegin(GL11.GL_QUADS); // Use A 16x16 pixel Quad For Each Character
GL11.glTexCoord2f(cx, 1 - cy - 0.0625f); // Texture Coord (Bottom Left)
GL11.glVertex2i(0, 0);
GL11.glTexCoord2f(cx + 0.0625f, 1 - cy - 0.0625f); // Texture Coord (Bottom Right)
GL11.glVertex2i(16, 0);
GL11.glTexCoord2f(cx + 0.0625f, 1 - cy); // Texture Coord (Top Right)
GL11.glVertex2i(16, 16);
GL11.glTexCoord2f(cx, 1 - cy); // Texture Coord (Top Left)
GL11.glVertex2i(0, 16);
GL11.glEnd(); // Done Building Our Quad (Character)
GL11.glTranslatef(fontWidth, 0, 0); // Move To The Right Of The Character
GL11.glEndList(); // Done Building The Display List
} // Loop Until All 256 Are Built
}
/**
* Clean up the allocated display lists for the character set.
*/
public void destroyFont()
{
if (fontListBase != -1) {
GL11.glDeleteLists(fontListBase,256);
fontListBase = -1;
}
}
/**
* Render a text string onto the screen, using the character set created
* by buildCharSet().
*/
public void glPrint(int x, int y, int set, String msg)
{
int offset = fontListBase - 32 + (128 * set);
if (fontListBase == -1 || fontTextureHandle == -1) {
System.out.println("glPrint(): character set has not been created -- run buildFont() first");
return;
}
if (msg != null) {
// enable the charset texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureHandle);
// prepare to render in 2D
setOrthoOn();
// draw the text
GL11.glTranslatef(x, y, 0); // Position The Text (in pixels coords)
for(int i=0; i<msg.length(); i++) {
GL11.glCallList(offset + msg.charAt(i));
}
// restore the original positions and views
setOrthoOff();
}
}
/**
* Render a text string in model space, using the character set created
* by buildFont().
*/
public void glText(float x, float y, float z, int set, float scale, String msg)
{
int offset = fontListBase - 32 + (128 * set);
if (fontListBase == -1 || fontTextureHandle == -1) {
System.out.println("GLApp.glPrint(): character set has not been created -- run buildCharSet() first");
return;
}
if (msg != null) {
// enable the charset texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureHandle);
// draw the text
GL11.glPushMatrix();
{
GL11.glTranslatef(x, y, z); // Position The Text
GL11.glScalef(scale,scale,scale); // make it smaller (arbitrary kludge!!!!)
for (int i = 0; i < msg.length(); i++) {
GL11.glCallList(offset + msg.charAt(i));
}
}
GL11.glPopMatrix();
}
}
/**
* Set OpenGL to render in flat 2D (no perspective) on top of current scene.
* Preserve current projection and model views, and disable depth testing.
* Once Ortho is On, glTranslate() will take pixel coords as arguments,
* with the lower left corner 0,0 and the upper right corner 1024,768 (or
* whatever your screen size is).
*
* @see setOrthoOff()
*/
public void setOrthoOn()
{
GL11.glDisable(GL11.GL_DEPTH_TEST); // so text stays on top of scene
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix(); // preserve perspective view
GL11.glLoadIdentity(); // clear the perspective matrix
GL11.glOrtho(0,displayMode.getWidth(),0,displayMode.getHeight(),-1,1); // turn on 2D mode
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix(); // Preserve the Modelview Matrix
GL11.glLoadIdentity(); // clear the Modelview Matrix
}
/**
* Turn 2D mode off. Return the projection and model views to their
* preserved state that was saved when setOrthoOn() was called, and
* enable depth testing.
*
* @see setOrthoOn()
*/
public void setOrthoOff()
{
// restore the original positions and views
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_DEPTH_TEST); // turn Depth Testing back on
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -