OpenGL Mipmap Texture_2D - java

I am very new in openGL and I use LWJGL.
I do not know how to see if "Mipmaps are working"
This is how I load a Image (64x64) :
private int loadPNGTexture(String filename) {
ByteBuffer buf = null;
int tWidth = 0;
int tHeight = 0;
try {
InputStream in = new FileInputStream(ClassLoader.getSystemResource(filename).getPath());
decoder = new PNGDecoder(in);
tWidth = decoder.getWidth();
tHeight = decoder.getHeight();
buf = BufferUtils.createByteBuffer(4 * decoder.getWidth() * decoder.getHeight());
decoder.decode(buf, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);
buf.flip();
in.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
int texId = GL11.glGenTextures();
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texId);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tWidth, tHeight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
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);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
return texId;
}
And this is how I draw my Image :
public void drawGL() {
GL11.glPushMatrix();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, playerTextures[0]);
GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2f(decoder.getWidth(), 0);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2f(decoder.getWidth(), decoder.getWidth());
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2f(0, decoder.getWidth());
GL11.glEnd();
GL11.glPopMatrix();
}
The draw is correct, I can see my Image but if I change the DisplayMode (from 800x600 to 1280x960), the Image is not growing up. So the problem is that I need the Image grow up to scale with the resolution.

Related

Skybox textures is transparent

My skybox is displayed, but does not display the textures that I load from the image. Instead, it shows the transparent color if i set glTexImage2D how GL_RGBA, or black color if i set glTexImage2D how GL_RGB.
I am using a render with MultisampledFbo support.
My texture loading code looks like this:
private int loadSkyboxTextures(){
glGenBuffers(vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glGenVertexArrays(vao);
glBindVertexArray(vao[0]);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glVertexPointer(3, GL_FLOAT, 3 * Float.BYTES, NULL);
glTexCoordPointer (3, GL_FLOAT, 3 * Float.BYTES, NULL);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
int texID = glGenTextures();
glBindTexture(GL_TEXTURE_CUBE_MAP, texID);
for(int i = 0; i < TEXTURE_FILES.length; i++){
InputStream file = getClass().getResourceAsStream(TEXTURE_FILES[i]);
byte[] pixelData = new byte[0];
try {
pixelData = new byte[file.available()];
file.read(pixelData);
} catch (IOException e) {
e.printStackTrace();
}
ByteBuffer byteBuffer = ByteBuffer.wrap(pixelData);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 512, 512, 0,
GL_RGB, GL_UNSIGNED_BYTE, byteBuffer);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
return texID;
}
Cube Render Code:
private void drawSkybox(){
glColor4f(1,1,1,1);
glDepthMask(false);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBindVertexArray(vao[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glDepthMask(true);
glDisable(GL_TEXTURE_CUBE_MAP);
}
The cube rendering call in the main render function:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
view = viewX || viewY || viewZ;
if(view)
glPushMatrix();
int rot = 180;
glDisable(GL_LIGHTING);
glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-max, max, -1, 1, 10, -10);
glRotated(cameraX, 1f, 0f, 0);
glRotated(cameraY, 0f, 1f, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawSkybox(texId);
glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
...
//render camera and other objects
For cube map textures, the texture coordinates are 3-dimensional and treated as a vector form the center of the cube map.
Since you draw a cube, which is centered around (0, 0, 0), you can use the the vertex coordinates for the texture coordinates, too. You do not use a shader program, so you have to use fixed function attributes. Specify the vertex coordinates by glVertexPointer and the texture coordinates by glTexCoordPointer. Enable the client-side capability (glEnableClientState) GL_VERTEX_ARRAY and GL_TEXTURE_COORD_ARRAY.
Specify the Vertex Array Object. It is sufficient to execute that code once at intialization:
glGenBuffers(vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glGenVertexArrays(vao);
glBindVertexArray(vao[0]);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glVertexPointer(3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glTexCoordPointer (3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindVertexArray(0);
When you draw the skybox it is sufficient to bind the cubemap texture to enable cube-mapped texturing and to bind the VAO:
private void drawSkybox(){
GL11.glColor4f(1,1,1,1);
glDepthMask(false);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, texID);
glBindVertexArray(vao[0]);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthMask(true);
glDisable(GL_TEXTURE_CUBE_MAP);
}
There are some further issues:
The image is not read correctly. See I have a black texture.
Clear the depth buffer after drawing the skybox. See Skybox textures do not display correctly

Some parts are missing when render 3D object in android(java) using OpenGLES 2

I'm new to OpenGL, and I am trying to load a .obj file into my Android application and display it using OpenGLES 2. The object is rendered. But there are some spaces in it like the below image. How can I fix this?
This is the actual object.
Here is my code (additional: I'm using this in MaxST Instant tracker)
objLoader = new ObjLoader(context, "andy.obj");
numFaces = objLoader.numFaces;
positions = ByteBuffer.allocateDirect(objLoader.positions.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
positions.put(objLoader.positions).position(0);
normals = ByteBuffer.allocateDirect(objLoader.normals.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
normals.put(objLoader.normals).position(0);
textureCoordinates = ByteBuffer.allocateDirect(objLoader.textureCoordinates.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordinates.put(objLoader.textureCoordinates).position(0);
ByteBuffer bb = ByteBuffer.allocateDirect(objLoader.positions.length * Float.SIZE / 8);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(positions);
vertexBuffer.position(0);
bb = ByteBuffer.allocateDirect(objLoader.textureCoordinates.length * Float.SIZE / 8);
bb.order(ByteOrder.nativeOrder());
textureCoordBuff = bb.asFloatBuffer();
textureCoordBuff.put(textureCoordinates);
textureCoordBuff.position(0);
shaderProgramId = ShaderUtil.createProgram(VERTEX_SHADER_SRC, FRAGMENT_SHADER_SRC);
positionHandle = GLES20.glGetAttribLocation(shaderProgramId, "a_position");
textureCoordHandle = GLES20.glGetAttribLocation(shaderProgramId, "a_texCoord");
mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgramId, "u_mvpMatrix");
textureHandle = GLES20.glGetUniformLocation(shaderProgramId, "u_texture");
textureNames = new int[1];
GLES20.glGenTextures(1, textureNames, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureNames[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
(ObjLoader class is from here)
Here is my draw method
#Override
public void draw() {
GLES20.glUseProgram(shaderProgramId);
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false,
0, vertexBuffer);
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(textureCoordHandle, 2, GLES20.GL_FLOAT, false,
0, textureCoordBuff);
GLES20.glEnableVertexAttribArray(textureCoordHandle);
Matrix.setIdentityM(modelMatrix, 0);
Matrix.multiplyMM(modelMatrix, 0, translation, 0, rotation, 0);
Matrix.multiplyMM(modelMatrix, 0, modelMatrix, 0, scale, 0);
Matrix.multiplyMM(modelMatrix, 0, transform, 0, modelMatrix, 0);
Matrix.multiplyMM(localMvpMatrix, 0, projectionMatrix, 0, modelMatrix, 0);
GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, localMvpMatrix, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glUniform1i(textureHandle, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureNames[0]);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, objLoader.positions.length / 3);
GLES20.glDisableVertexAttribArray(positionHandle);
GLES20.glDisableVertexAttribArray(textureCoordHandle);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
}
The model file seems to consist of quads. If the faces are quads, the you have to generate 2 triangles for each face.
Adapt the object loader. e.g.:
class ObjLoader {
// [...]
public ObjLoader(Context context, String file) {
// [...]
switch (parts[0]) {
// [...]
case "f":
// faces: vertex/texture/normal
if (parts.length == 5) {
// triangle 1
faces.add(parts[1]);
faces.add(parts[2]);
faces.add(parts[3]);
// triangle 2
faces.add(parts[1]);
faces.add(parts[3]);
faces.add(parts[4]);
}
else {
faces.add(parts[1]);
faces.add(parts[2]);
faces.add(parts[3]);
}
break;
}
// [...]
}
}

Textured Quad issue in Java OpenGL

First, I'll start with my code because I've identified which block is causing the issue.
// init
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glEnable(GL11.GL_TEXTURE_2D);
// BEGINNING OF OFFENDING CODE
BufferedImage image = ImageIO.read(new File("res/button.png"));
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
IntBuffer buffer = BufferUtils.createIntBuffer(pixels.length);
for (int pixel : pixels)
buffer.put(pixel);
buffer.flip();
int button = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
//Setup wrap mode
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
// END OF OFFENDING CODE
This is what things are supposed to look like without the textured quad.
This is what happens when I render with the offending code (with the textured quad).
This is what happens when I render with the offending code (without the textured quad).
For reference, this is the texture
I can't seem to figure out which GL11 call is affecting the rest of the Display and why it would be affecting the rest of the display. From what I understand, all of the calls that follow GL11.glBindTexture are limited to the bound texture, aren't they?
Edit: Additional Rendering Code
private static void renderQuad(int x, int y, int width, int height) {
GL11.glPushMatrix();
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(x, y);
GL11.glVertex2f(x + width, y);
GL11.glVertex2f(x + width, y + height);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
}
The method used for the red quads.
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glColor3f(0.5f,0.5f,1.0f);
renderQuad(0, 0, 800, 600);
// render action bar
GL11.glColor3f(0.2f,0.2f,1.0f);
renderQuad(0, 0, 800, 200);
GL11.glColor3f(1.0f,0.0f,0.0f);
renderQuad(50, 50, 100, 60);
renderQuad(200, 50, 100, 60);
// render textured quad
GL11.glPushMatrix();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(0.0,1.0);
GL11.glVertex2f(x, y);
GL11.glTexCoord2d(1.0,1.0);
GL11.glVertex2f(x + width, y);
GL11.glTexCoord2d(1.0,0.0);
GL11.glVertex2f(x + width, y + height);
GL11.glTexCoord2d(0.0,0.0);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
First of all, I think there's a problem with your texture loading. I believe the order of the bytes is reversed or something similar, which is why you get the red on black. Here's a working load-texture-from-BufferedImage example taken from my own code:
BufferedImage image = ImageIO.read(new File("<file path>.png"));
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);
for(int y = 0; y < image.getHeight(); y++){
for(int x = 0; x < image.getWidth(); x++){
int pixel = pixels[y * image.getWidth() + x];
buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
buffer.put((byte) (pixel & 0xFF)); // Blue component
buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA
}
}
buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS
// You now have a ByteBuffer filled with the color data of each pixel.
// Now just create a texture ID and bind it. Then you can load it using
// whatever OpenGL method you want, for example:
int textureID = GL11.glGenTextures(); //Generate texture ID
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID); //Bind texture ID
//Setup wrap mode
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
//Setup texture scaling filtering
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
//Send texel data to OpenGL
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
Now, to the actual rendering problem:
For OpenGL, GL_TEXTURE_2D must be enabled or disabled depending on whether or not the polygon you are drawing is textured. If you do not supply texture coordinates for each vertex, then the last texture coords call still holds and is used for each vertex. So, you'll get a quad using one pixel's worth of texture. This is what's causing the black quads - it's taking from one pixel from a corner of your improperly loaded texture. So, your fixed rendering code:
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glColor3f(0.5f,0.5f,1.0f);
renderQuad(0, 0, 800, 600);
// render action bar
GL11.glColor3f(0.2f,0.2f,1.0f);
renderQuad(0, 0, 800, 200);
GL11.glColor3f(1.0f,0.0f,0.0f);
renderQuad(50, 50, 100, 60);
renderQuad(200, 50, 100, 60);
GL11.glEnable(GL11.GL_TEXTURE_2D);
// render textured quad
GL11.glColor3f(1.0f, 1.0f, 1.0f);
GL11.glPushMatrix();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, button);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(0.0,1.0);
GL11.glVertex2f(x, y);
GL11.glTexCoord2d(1.0,1.0);
GL11.glVertex2f(x + width, y);
GL11.glTexCoord2d(1.0,0.0);
GL11.glVertex2f(x + width, y + height);
GL11.glTexCoord2d(0.0,0.0);
GL11.glVertex2f(x, y + height);
GL11.glEnd();
GL11.glPopMatrix();
On a side note, you can use simply glEnable() instead of GL11.glEnable() if you do:
import static org.lwjgl.opengl.GL11.*;
instead of simply
import org.lwjgl.opengl.GL11;

OpenGL Textures without Slick

I searched for Texture Implementations without the Slick Utils library.
I found 2 ways, to do this:
The first, saves the pixels with strange byteshifting in a byte buffer:
int loadTexture(){
try{
BufferedImage img = ImageIO.read(getClass().getClassLoader().getResourceAsStream("background.png"));
int pixels[] = new int[img.getWidth() * img.getHeight()];
img.getRGB(0, 0, img.getWidth(), img.getHeight(), pixels, 0, img.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(img.getWidth() * img.getHeight() * 3);
for(int x = 0; x < img.getWidth(); x++){
for(int y = 0; y < img.getHeight(); y++){
int pixel = pixels[y * img.getWidth() + x];
buffer.put((byte) ((pixel >> 16) & 0xFF));
buffer.put((byte) ((pixel >> 8) & 0xFF));
buffer.put((byte) (pixel & 0xFF));
}
}
buffer.flip();
int textureId = glGenTextures();
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, img.getWidth(), img.getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
return textureId;
}
catch(Exception e){
e.printStackTrace();
return 0;
}
}
This returns a texture id as well, and i haven't any idea how tu use this id.
The second way doesnt do any byteshifting, and uses a IntBuffer: Also, it is a ready class to save different textures with names and so on.
The Code of these:
ublic class TextureIO {
private final IntBuffer texture;
private final int width;
private final int height;
private int id;
public TextureIO(final InputStream inputStream) throws IOException {
BufferedImage image = ImageIO.read(inputStream);
width = image.getWidth();
height = image.getHeight();
final AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -height);
final AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
image = op.filter(image, null);
final int[] pixels = image.getRGB(0, 0, width, height, null, 0, width);
texture = BufferUtils.createIntBuffer(pixels.length);
texture.put(pixels);
texture.rewind();
}
public void init() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
final IntBuffer buffer = BufferUtils.createIntBuffer(1);
GL11.glGenTextures(buffer);
id = buffer.get(0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, texture);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
public void bind() {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
}
public void unbind() {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
}
Im really new to lwjgl development, and want to know which version is better. Cause im a friend of implementing such things by myself, i want the lwjgl.jar to be the own library im using.
I read on different sites, the buffer.flip() method would be necassary. but why? And why the second version doesnt do this? Also, i want to understand the difference between this two implementations, what happens in the first and what in the second?
Thank you!
Both of those are pretty bad implementations IMO. I would recommend watching this video for a more standard approach. Although you would have to also use the PNGDecoder.jar library it is like an extension to the lwjgl library.

GL11 Texture rendering wrong

I'm trying to render an image on a basic quad, I took a look at the Space Invaders Example Game for the code, and implemented that code into mine. The image gets renderer on screen, with the right colors, but the image seems shifted. This is the image I'm trying to render:
http://img203.imageshack.us/img203/5264/testwq.png
This is how it renders:
http://img593.imageshack.us/img593/6849/test2uh.png
The image is 128x128, and so is the quad.
Here is my code:
public class RenderEngine
{
private IntBuffer intbuf = BufferUtils.createIntBuffer(1);
private ColorModel glAlphaColorModel;
private ColorModel glColorModel;
public RenderEngine()
{
this.glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 8 }, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
this.glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 0 }, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
}
public void bindTexture(String filename)
{
try
{
File file = new File(CivilPolitica.instance.getDir(), "resources/" + filename);
FileInputStream fis = new FileInputStream(file);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.getTexture(fis));
fis.close();
}
catch (Exception e)
{
e.printStackTrace();
System.exit(0);
}
}
private int getTexture(InputStream in)
{
try
{
GL11.glGenTextures(this.intbuf);
int id = this.intbuf.get(0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
BufferedImage bi = ImageIO.read(in);
int format = bi.getColorModel().hasAlpha() ? GL11.GL_RGBA : GL11.GL_RGB;
ByteBuffer texData;
WritableRaster raster;
BufferedImage texImage;
int texWidth = 2;
int texHeight = 2;
while (texWidth < bi.getWidth())
{
texWidth *= 2;
}
while (texHeight < bi.getHeight())
{
texHeight *= 2;
}
if (bi.getColorModel().hasAlpha())
{
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 4, null);
texImage = new BufferedImage(this.glAlphaColorModel, raster, false, new Hashtable<String, Object>());
}
else
{
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, texWidth, texHeight, 3, null);
texImage = new BufferedImage(this.glColorModel, raster, false, new Hashtable<String, Object>());
}
Graphics g = texImage.getGraphics();
g.setColor(new Color(0f, 0f, 0f, 0f));
g.fillRect(0, 0, texWidth, texHeight);
g.drawImage(bi, 0, 0, null);
byte[] data = ((DataBufferByte) texImage.getRaster().getDataBuffer()).getData();
texData = ByteBuffer.allocateDirect(data.length);
texData.order(ByteOrder.nativeOrder());
texData.put(data, 0, data.length);
texData.flip();
glTexParameteri(GL11.GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
glTexParameteri(GL11.GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, bi.getWidth(), bi.getHeight(), 0, format, GL_UNSIGNED_BYTE, texData);
return id;
}
catch (Exception e)
{
e.printStackTrace();
System.exit(0);
return 0;
}
}
}
And the actual quad:
CivilPolitica.instance.renderer.bindTexture("test.png");
GL11.glPushMatrix();
GL11.glTranslatef(128, 128, 0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2i(0, 0);
GL11.glTexCoord2f(0, 127);
GL11.glVertex2i(0, 128);
GL11.glTexCoord2f(127, 127);
GL11.glVertex2i(128, 128);
GL11.glTexCoord2f(127, 0);
GL11.glVertex2i(128, 0);
GL11.glEnd();
GL11.glPopMatrix();
GL11.glTexCoord2f(0, 0);
GL11.glVertex2i(0, 0);
GL11.glTexCoord2f(0, 127);
GL11.glVertex2i(0, 128);
GL11.glTexCoord2f(127, 127);
GL11.glVertex2i(128, 128);
GL11.glTexCoord2f(127, 0);
GL11.glVertex2i(128, 0);
must be
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glVertex2i(0, 0);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glVertex2i(0, 128);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glVertex2i(128, 128);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glVertex2i(128, 0);
because it are texture coordinates from 0.0f to 1.0f (0.0f ist the one side and 1.0f is the other, that way it is not resolution dependent)

Categories

Resources