Prinzipielle Frage an den TE: Wieso werden die vier kleineren Texturen nicht gleich direkt als eine große abgespeichert und zb. via glTexSubImage verwendet?
Warte mal bis Fancy vorbeischaut, der schüttelt dir das aus dem Ärmel
Nett gemeint aber ich brauche das reale kopieren in eine neue Textur. Ich habe gedacht das geht einfach irgendwie mit Pixel-Copy innerhalb der Grafikkarte mit GL Befehlen.
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.imageio.ImageIO;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLBuffers;
public class Merge implements GLEventListener {
private static final String IMAGES[] = { "test.png", "test2.png" };
private static final float[] QUAD_XYZ = new float[] { -0.5f, -0.5f, 0f, +0.5f, -0.5f, 0f, +0.5f, +0.5f, 0f, -0.5f, +0.5f, 0f };
private static final float[] QUAD_ST = new float[] { 0f, 0f, 1f, 0f, 1f, 1f, 0f, 1f };
private final FloatBuffer vaXYZ = GLBuffers.newDirectFloatBuffer(QUAD_XYZ);
private final FloatBuffer vaST = GLBuffers.newDirectFloatBuffer(QUAD_ST);
private final IntBuffer buffer = GLBuffers.newDirectIntBuffer(1);
private final int[] textureHandles = new int[IMAGES.length + 1];
private GL2 gl;
private GLU glu;
private int createTexture(final String resource) {
try {
final BufferedImage image = ImageIO.read(getClass().getClassLoader().getResourceAsStream(resource));
final byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
final ByteBuffer texture = GLBuffers.newDirectByteBuffer(data);
gl.glGenTextures(1, buffer);
final int textureHandle = buffer.get(0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandle);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
gl.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 1);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGB, image.getWidth(), image.getHeight(), 0, GL2.GL_BGR, GL2.GL_UNSIGNED_BYTE, texture);
return textureHandle;
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
private int merge(final int textureHandle1, final int textureHandle2, final int width, final int height) {
gl.glGenFramebuffers(1, buffer);
final int frameBufferHandle = buffer.get(0);
gl.glGenRenderbuffers(1, buffer);
final int renderBufferHandle = buffer.get(0);
gl.glGenTextures(1, buffer);
final int textureHandle = buffer.get(0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBufferHandle);
gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, renderBufferHandle);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandle);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGB, width, height, 0, GL2.GL_RGB, GL2.GL_UNSIGNED_BYTE, null);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, GL2.GL_COLOR_ATTACHMENT0, GL2.GL_TEXTURE_2D, textureHandle, 0);
gl.glRenderbufferStorage(GL2.GL_RENDERBUFFER, GL2.GL_DEPTH_COMPONENT24, width, height);
gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, GL2.GL_RENDERBUFFER, renderBufferHandle);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glOrthof(-1f, 1f, -1f, 1f, -1f, 1f);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glViewport(0, 0, width, height);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glScalef(1f, 2f, 1f);
gl.glTranslatef(-0.5f, 0.0f, 0.0f);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandle1);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, vaST);
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, vaXYZ);
gl.glDrawArrays(GL2.GL_QUADS, 0, vaXYZ.capacity());
gl.glTranslatef(1.0f, 0.0f, 0.0f);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandle2);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, vaST);
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, vaXYZ);
gl.glDrawArrays(GL2.GL_QUADS, 0, vaXYZ.capacity());
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glPopMatrix();
gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
buffer.put(0, renderBufferHandle);
gl.glDeleteRenderbuffers(GL2.GL_RENDERBUFFER, buffer);
buffer.put(0, frameBufferHandle);
gl.glDeleteFramebuffers(GL2.GL_FRAMEBUFFER, buffer);
return textureHandle;
}
@Override
public void init(final GLAutoDrawable drawable) {
gl = drawable.getGL().getGL2();
glu = new GLU();
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glEnable(GL2.GL_TEXTURE_2D);
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
for (int i = 0; i < IMAGES.length; i++)
textureHandles[i] = createTexture(IMAGES[i]);
textureHandles[IMAGES.length] = merge(textureHandles[0], textureHandles[1], 1024, 1024);
}
@Override
public void display(final GLAutoDrawable drawable) {
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(-3f, 0.0f, -5.0f);
for (int i = 0; i < IMAGES.length + 1; i++) {
gl.glTranslatef(+1.5f, 0.0f, 0.0f);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandles[i]);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, vaST);
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, vaXYZ);
gl.glDrawArrays(GL2.GL_QUADS, 0, vaXYZ.capacity());
}
}
@Override
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, int height) {
if (height <= 0)
height = 1;
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0f, (float) width / (float) height, 1.0, 20.0);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void dispose(final GLAutoDrawable arg0) {
}
public static void main(final String[] args) throws IOException {
final Merge base = new Merge();
final Frame frame = new Frame();
final GLCanvas canvas = new GLCanvas();
final Animator animator = new Animator(canvas);
canvas.addGLEventListener(base);
frame.add(canvas);
frame.setSize(500, 500);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent e) {
new Thread(new Runnable() {
public void run() {
animator.stop();
System.exit(0);
}
}).start();
}
});
frame.setLocationRelativeTo(null);
frame.setVisible(true);
animator.start();
}
}
theoretisch könnte man das auch per shader machen den man das asci alphabet (für adavnced das unicode) mithilfe on uniforms übergibt ^^ der das dann selber auf den fragmentshader berechnet. Wäre mal nen interessantes Projekt, aber wie über mir schon gesagt, text ist eigentlich nicht das problem. Ich empfehle halt alle befelhe als Displaylist zu speichern, dann gehen die aufrufe auch super schnell Performance Probleme bei 2-3k zeichen wenn du die als eigene texture hast entstehen nur durch die von dir manuell aufgerufenen draw calls und texturestate changes.
Hat jemand dafür eine Lösung?Wenn ich das obige Beispiel unter LWJGL laufen lassen möcht... was ist die Alternative zu "GLBuffers" ?
Du hast doch nur eine Textur und deinen Text. Auf der Textur liegen die Buchstaben und Zahlen und Sonderzeichen herum. Mittels derer Position kannst du dir die gewünschten Texel nehmen und auf einem Quad zeichnen.Aber ist es nicht performanter, wenn die Grafikkarte nur 1 Textur mit dem ganzen Text darstellen muss? Da spart man sich doch den ganzen Darstelleungskram von 2-3K Buchstaben die durch die Grafikkarte sausen müssten. Man stelle sich eine Textverarbeitung in OpenGL vor. Ich denke da ist es mit einer Textur besser.
jeden Buchstaben ein Rechteck auf dem Screen zeichnen. Das geht natürlich bei langem Text nicht. Denn bei spätestens 2.500-5.000 wirds eng (jedenfalls bei meinem Rechner).
Kann mir einer einen Link zu aktuellen compilierten JOGL 2 (July 2010) Dateien geben (Mac)?
Wenn ich das obige Beispiel unter LWJGL laufen lassen möcht... was ist die Alternative zu "GLBuffers" ?
FloatBuffer vaXYZ = GLBuffers.newDirectFloatBuffer(QUAD_XYZ);
FloatBuffer vaXYZ = ByteBuffer.allocateDirect(Float.SIZE / Byte.SIZE * QUAD_XYZ.length).order(ByteOrder.nativeOrder()).asFloatBuffer();
vaXYZ.put(QUAD_XYZ);
vaXYZ.rewind();
theoretisch könnte man das auch per shader machen
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.imageio.ImageIO;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLBuffers;
public class Text implements GLEventListener {
private static int WIDTH = 10;
private static int HEIGHT = 1;
private static final String staticVS = "" +
"#version 130\n" +
"uniform int text[" + WIDTH * HEIGHT + "];" +
"out vec2 st;" +
"void main(void) " +
"{" +
" int i = text[gl_VertexID / 6];" +
" float s1 = i * (1 / 26.0) - 0.002;" +
" float s2 = s1 + (1 / 26.0 - 0.002);" +
" st = vec2(s1, 1);" +
" if((gl_VertexID % 6) == 1) st = vec2(s2, 1);" +
" else if((gl_VertexID % 6) == 2) st = vec2(s2, 0);" +
" else if((gl_VertexID % 6) == 3) st = vec2(s1, 1);" +
" else if((gl_VertexID % 6) == 4) st = vec2(s2, 0);" +
" else if((gl_VertexID % 6) == 5) st = vec2(s1, 0);" +
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;" +
"}";
private static final String staticFS = "" +
"uniform sampler2D tex;" +
"in vec2 st;" +
"void main (void)" +
"{" +
" gl_FragColor = texture2D(tex, st);" +
"}";
private static final String IMAGE = "abc.png";
private static final float[] TRIANGLE_XY = { -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f };
private final IntBuffer buffer = GLBuffers.newDirectIntBuffer(1);
private final IntBuffer text = GLBuffers.newDirectIntBuffer(WIDTH * HEIGHT);
private final FloatBuffer va;
private int shaderHandle;
private int textureHandle;
private int textHandle;
private GL2 gl;
private GLU glu;
public Text() {
va = GLBuffers.newDirectFloatBuffer(TRIANGLE_XY.length * WIDTH * HEIGHT);
for (int y = 0; y < HEIGHT; y++)
for (int x = 0; x < WIDTH; x++)
for (int i = 0; i < TRIANGLE_XY.length; i++)
if (i % 2 == 0)
va.put((TRIANGLE_XY[i] + x + 0.5f - WIDTH / 2.0f) / WIDTH);
else
va.put((TRIANGLE_XY[i] + y + 0.5f - HEIGHT / 2.0f) / HEIGHT);
va.rewind();
}
private int createTexture(final String resource) {
try {
final BufferedImage image = ImageIO.read(getClass().getClassLoader().getResourceAsStream(resource));
final byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
final ByteBuffer texture = GLBuffers.newDirectByteBuffer(data);
gl.glGenTextures(1, buffer);
final int textureHandle = buffer.get(0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandle);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
gl.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 1);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGBA, image.getWidth(), image.getHeight(), 0, GL.GL_RGBA, GL2.GL_UNSIGNED_INT_8_8_8_8, texture);
return textureHandle;
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
private int createShader() {
final int vHandle = gl.glCreateShader(GL2.GL_VERTEX_SHADER);
gl.glShaderSource(vHandle, 1, new String[] { staticVS }, new int[] { staticVS.length() }, 0);
gl.glCompileShader(vHandle);
final int fHandle = gl.glCreateShader(GL2.GL_FRAGMENT_SHADER);
gl.glShaderSource(fHandle, 1, new String[] { staticFS }, new int[] { staticFS.length() }, 0);
gl.glCompileShader(fHandle);
final int spHandle = gl.glCreateProgram();
gl.glAttachShader(spHandle, vHandle);
gl.glAttachShader(spHandle, fHandle);
gl.glLinkProgram(spHandle);
gl.glValidateProgram(spHandle);
gl.glUseProgram(spHandle);
textHandle = gl.glGetUniformLocation(spHandle, "text");
return spHandle;
}
@Override
public void init(final GLAutoDrawable drawable) {
gl = drawable.getGL().getGL2();
glu = new GLU();
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glEnable(GL2.GL_TEXTURE_2D);
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
shaderHandle = createShader();
textureHandle = createTexture(IMAGE);
}
private void setText(final String value) {
for (int i = 0; i < value.length() && i < text.capacity(); i++)
text.put(i, value.charAt(i) - 'A');
gl.glUseProgram(shaderHandle);
gl.glUniform1iv(textHandle, value.length(), text);
}
@Override
public void display(final GLAutoDrawable drawable) {
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0f, 0.0f, -2.0f);
gl.glScalef(1f, 0.2f, 1f);
setText("HELLOWORLD");
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandle);
gl.glVertexPointer(2, GL2.GL_FLOAT, 0, va);
gl.glDrawArrays(GL2.GL_TRIANGLES, 0, va.capacity());
}
@Override
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, int height) {
if (height <= 0)
height = 1;
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0f, (float) width / (float) height, 1.0, 20.0);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void dispose(final GLAutoDrawable arg0) {
}
public static void main(final String[] args) throws IOException {
final Text base = new Text();
final Frame frame = new Frame();
final GLCanvas canvas = new GLCanvas();
final Animator animator = new Animator(canvas);
canvas.addGLEventListener(base);
frame.add(canvas);
frame.setSize(500, 500);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent e) {
new Thread(new Runnable() {
public void run() {
animator.stop();
System.exit(0);
}
}).start();
}
});
frame.setLocationRelativeTo(null);
frame.setVisible(true);
animator.start();
}
}
Moin,
Gruß,
Fancy
Das Ergebnis ist dann:
(Man sieht, ich habe mir beim erstellen der ABC Textur nicht sonderlich viel Mühe gegeben. Unter anderem auch nur Großbuchstaben und kein Leerzeichen. Wollte man das ordentlich machen, werden insbesondere nicht monospace Schriftarten schwierig.)
Wer es trotzdem ausprobieren möchte, hier die abc.png
Gruß,
Fancy
zum Merge Code:
Da bekomme ich das was Du auf dem Screenshot siehst (ein zerstörtes Bild). Woran könnte das liegen? Ich habe zwei 1024x1024 PNG's verwendet.
Auch beim 2. Beispiel "Text" sehe ich nur Schwarz (leer).
private void printShaderError(final int handle) {
gl.glGetShaderiv(handle, GL2.GL_COMPILE_STATUS, buffer);
if (buffer.get(0) != 1) {
gl.glGetShaderiv(handle, GL2.GL_INFO_LOG_LENGTH, buffer);
final ByteBuffer byteBuffer = GLBuffers.newDirectByteBuffer(buffer.get(0));
gl.glGetShaderInfoLog(handle, byteBuffer.capacity(), buffer, byteBuffer);
System.err.println("\nshader compile error: " + handle);
for (int i = 0; i < buffer.get(0); i++)
System.err.print((char) byteBuffer.get(i));
}
}
private int createShader() {
final int vHandle = gl.glCreateShader(GL2.GL_VERTEX_SHADER);
gl.glShaderSource(vHandle, 1, new String[] { staticVS }, new int[] { staticVS.length() }, 0);
gl.glCompileShader(vHandle);
printShaderError(vHandle);
final int fHandle = gl.glCreateShader(GL2.GL_FRAGMENT_SHADER);
gl.glShaderSource(fHandle, 1, new String[] { staticFS }, new int[] { staticFS.length() }, 0);
gl.glCompileShader(fHandle);
printShaderError(fHandle);
final int spHandle = gl.glCreateProgram();
gl.glAttachShader(spHandle, vHandle);
gl.glAttachShader(spHandle, fHandle);
gl.glLinkProgram(spHandle);
gl.glValidateProgram(spHandle);
gl.glUseProgram(spHandle);
textHandle = gl.glGetUniformLocation(spHandle, "text");
return spHandle;
}
Anbei die 2 PNG's für "Merge" (im Original sind diese 1024x1024)
Schalte ich Transparenz bei beien PNG's aus, erhalte ich Screenshot 3
Hier die Ausgabe von "Text":
shader compile error: 1
ERROR: 0:1: '' : Version number not supported by GL2
ERROR: 0:2: 'out' : syntax error syntax error
ERROR: Parser found no code to compile in source strings.
shader compile error: 2
ERROR: 0:1: 'in' : syntax error syntax error
ERROR: Parser found no code to compile in source strings.
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.imageio.ImageIO;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLBuffers;
public class Text2 implements GLEventListener {
private static int WIDTH = 5;
private static int HEIGHT = 2;
private static final String IMAGE = "abc.png";
private static final float[] TRIANGLE_XY = { -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f };
private final IntBuffer buffer = GLBuffers.newDirectIntBuffer(1);
private final FloatBuffer vaXY;
private final FloatBuffer vaST;
private int textureHandle;
private GL2 gl;
private GLU glu;
public Text2() {
vaXY = GLBuffers.newDirectFloatBuffer(TRIANGLE_XY.length * WIDTH * HEIGHT);
vaST = GLBuffers.newDirectFloatBuffer(TRIANGLE_XY.length * WIDTH * HEIGHT);
for (int y = HEIGHT - 1; y >= 0; y--)
for (int x = 0; x < WIDTH; x++)
for (int i = 0; i < TRIANGLE_XY.length; i++)
if (i % 2 == 0)
vaXY.put((TRIANGLE_XY[i] + x + 0.5f - WIDTH / 2.0f) / WIDTH);
else
vaXY.put((TRIANGLE_XY[i] + y + 0.5f - HEIGHT / 2.0f) / HEIGHT);
vaXY.rewind();
}
private int createTexture(final String resource) {
try {
final BufferedImage image = ImageIO.read(getClass().getClassLoader().getResourceAsStream(resource));
final byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
final ByteBuffer texture = GLBuffers.newDirectByteBuffer(data);
gl.glGenTextures(1, buffer);
final int textureHandle = buffer.get(0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandle);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
gl.glPixelStorei(GL2.GL_UNPACK_ALIGNMENT, 1);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_RGBA, image.getWidth(), image.getHeight(), 0, GL.GL_RGBA, GL2.GL_UNSIGNED_INT_8_8_8_8, texture);
return textureHandle;
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void init(final GLAutoDrawable drawable) {
gl = drawable.getGL().getGL2();
glu = new GLU();
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glEnable(GL2.GL_TEXTURE_2D);
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
textureHandle = createTexture(IMAGE);
}
private void setText(final String value) {
for(int gl_VertexID = 0; gl_VertexID < value.length() * 6 && gl_VertexID < vaXY.capacity(); gl_VertexID++){
final int i = value.charAt(gl_VertexID / 6) - 'A';
final float s1 = (float) (i * (1 / 26.0) - 0.002);
final float s2 = (float) (s1 + (1 / 26.0 - 0.002));
float s = s1;
float t = 1;
if((gl_VertexID % 6) == 1) { s = s2; t = 1; }
else if((gl_VertexID % 6) == 2) { s = s2; t = 0; }
else if((gl_VertexID % 6) == 3) { s = s1; t = 1; }
else if((gl_VertexID % 6) == 4) { s = s2; t = 0; }
else if((gl_VertexID % 6) == 5) { s = s1; t = 0; }
vaST.put(gl_VertexID * 2, s);
vaST.put(gl_VertexID * 2 + 1, t);
}
}
@Override
public void display(final GLAutoDrawable drawable) {
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0f, 0.0f, -2.0f);
gl.glScalef(1f, 0.2f, 1f);
setText("HELLOWORLD");
gl.glBindTexture(GL2.GL_TEXTURE_2D, textureHandle);
gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, vaST);
gl.glVertexPointer(2, GL2.GL_FLOAT, 0, vaXY);
gl.glDrawArrays(GL2.GL_TRIANGLES, 0, vaXY.capacity());
}
@Override
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, int height) {
if (height <= 0)
height = 1;
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0f, (float) width / (float) height, 1.0, 20.0);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void dispose(final GLAutoDrawable arg0) {
}
public static void main(final String[] args) throws IOException {
final Text2 base = new Text2();
final Frame frame = new Frame();
final GLCanvas canvas = new GLCanvas();
final Animator animator = new Animator(canvas);
canvas.addGLEventListener(base);
frame.add(canvas);
frame.setSize(500, 500);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent e) {
new Thread(new Runnable() {
public void run() {
animator.stop();
System.exit(0);
}
}).start();
}
});
frame.setLocationRelativeTo(null);
frame.setVisible(true);
animator.start();
}
}