My skybox is displayed, but does not display the textures that I load from the image. Instead, it shows the black color.
I am using a render with MultisampledFbo support.
My texture loading code looks like this:
private int loadSkyboxTextures(){
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(){
glEnable(GL_TEXTURE_CUBE_MAP);
glDepthMask(false);
glGenBuffers(vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
glGenVertexArrays(vao);
glBindVertexArray(vao[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glEnableVertexAttribArray(0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
glDrawArrays(GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glDepthMask(true);
glBindBuffer (GL_ARRAY_BUFFER,0);
glDisable(GL_TEXTURE_CUBE_MAP);
}
The cube rendering call in the main render function:
glMatrixMode(GL_PROJECTION);
glOrtho(-max, max, -1, 1, 10, -10);
glRotated(cameraX, 1f, 0f, 0);
glRotated(cameraY, 0f, 1f, 0);
glGetFloatv(GL_PROJECTION_MATRIX, pm);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawSkybox();
glLoadIdentity();
...
//render other objects
Legacy OpenGL's texturing has to be enabled. To perform cube-mapped texturing, GL_TEXTURE_CUBE_MAP has to be enabled (see glEnable):
glEnable(GL_TEXTURE_CUBE_MAP);
Note, for cube map textures, the texture coordinates are 3-dimensional and treated as a vector form the center of the cube map.
Related
EDIT:
Fixed by putting:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
just after glEnable(GL_TEXTURE_2D); in the texture rendering method!
So, when I maximise my game's window, the textures will have lines between them, like this:
lines
However, when it's in 800x600, it looks like this:
what it looks like in 800x600
I am using Slick2d to load the textures, if that is what is causing the issue.
if (Display.wasResized()) {
glViewport(0, 0, Display.getWidth(), Display.getHeight());
}
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Enable alpha blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glViewport(0,0, Display.getWidth(), Display.getHeight());
glMatrixMode(GL_MODELVIEW);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
That is what is in the while(!Display.isCloseRequested()) loop.
My texture rendering method has this inside:
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
texture.bind();
glBegin(GL_QUADS);
glTexCoord2d(0, 0);
glVertex2d(x, y);
glTexCoord2d(1, 0);
glVertex2d(x + width, y);
glTexCoord2d(1, 1);
glVertex2d(x + width, y + height);
glTexCoord2d(0, 1);
glVertex2d(x, y + height);
glEnd();
glEnable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
Any help would be greatly appreciated :)
I'm trying to create some code for loading and drawing 2D textures in LWJGL. Here is my code for drawing:
glfwShowWindow(window);
GL.createCapabilities();
loadTextures();
glClearColor(1f, 1f, 1f, 1f);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//draw
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glTranslatef(100, 100, 0);
glBindTexture(GL_TEXTURE_2D, testTexture);
glBegin(GL_QUADS);
{
glTexCoord2f(0, 0);
glVertex2f(0, 0);
glTexCoord2f(1, 0);
glVertex2f(TEXTURE_WIDTH, 0);
glTexCoord2f(1, 1);
glVertex2f(TEXTURE_WIDTH, TEXTURE_HEIGHT);
glTexCoord2f(0, 1);
glVertex2f(0, TEXTURE_HEIGHT);
}
glEnd();
glPopMatrix();
//end draw
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
glfwSetErrorCallback(null).free();
And this is my texture loading code:
try
{
BufferedImage image = ImageIO.read(file);
/*
if (image.getType() != BufferedImage.TYPE_INT_ARGB)
{
throw new TextureException("Invalid image!");
}
*/
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer byteBuffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);
for (int x = 0; x < image.getWidth(); x++)
{
for (int y = 0; y < image.getHeight(); y++)
{
int pixel = pixels[y * image.getWidth() + x];
byteBuffer.put((byte)((pixel >> 16) & 0xFF));
byteBuffer.put((byte)((pixel >> 8) & 0xFF));
byteBuffer.put((byte)(pixel & 0xFF));
byteBuffer.put((byte)((pixel >> 24) & 0xFF));
}
}
byteBuffer.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_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, byteBuffer);
return textureID;
}
catch (Exception e)
{
e.printStackTrace();
throw new TextureException("Failed to load image!");
}
However, when I run this code all I get is a white screen. I checked the value of testTexture and it was set to 1, so I assume that's the texture's ID which makes me believe that worked, but I think there's something going wrong when drawing.
Two-dimensional texturing has to be enabled by glEnable and can be disabled by glDisable:
glEnable(GL_TEXTURE_2D);
If texturing is enables then the texture wich is currently bound is applied, when the geometry is drawn by the glBegin/glEnd sequences.
If you want to draw the geometry in window (pixel) coordinates, then you've to set an orthographic projection with. The orthographic projection can be set by glOrtho.
If you dont set the orthographic projection, the vertex coordinates would have to be in normalized device space in range [-1.0, 1.0].
In the following windowWidth an windowHeight is assumed to be the width and height of the window:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, windowWidth, windowHeight, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// [...]
}
I'm trying to draw to a 2d texture and to draw that texture in a 3D scene.
Code for Initializing the framebuffer objects and textures:
public static void initFBO()
{
renderEngine.framebuffers = new int[7];
renderEngine.monitorTextures = new int[7];
for(int i = 0;i < 7;i++)
{
renderEngine.framebuffers[i] = glGenFramebuffers();
renderEngine.monitorTextures[i] = glGenTextures();
glBindFramebuffer(GL_FRAMEBUFFER, renderEngine.framebuffers[i]);
glBindTexture(GL_TEXTURE_2D, renderEngine.monitorTextures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer)null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderEngine.monitorTextures[i], 0);
}
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
System.err.println("Error while creating FBO");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
Code for rendering a quad to the framebuffer:
glUseProgram(0);
for(int i = 0;i < 6;i++)
{
glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[i]);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, 512, 512);
glClearColor(0f, 0f, 0f, 1f);
glClear(GL_COLOR_BUFFER_BIT);
//glActiveTexture(GL_TEXTURE0);
//glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 512, 512, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glUseProgram(0);
glColor4f(1f, 0f, 0f, 1f);
glBegin(GL_QUADS);
glVertex2f(20, 20);
glVertex2f(420, 20);
glVertex2f(420, 420);
glVertex2f(20, 420);
glEnd();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glPopAttrib();
}
If i change the clear color, the texture gets that color when rendered in my 3D scene. But I'm unable to see the quad. Am i doing something the wrong way?
If found the solution. Cause I was using a 3D environement and had GL_CULL_FACE enabled and set to CCW (counterclockwise), the quad drawn clockwise was not shown.
I just disabled this before drawing to the framebuffer and reenabled it aftwerwards.
glDisable(GL_CULL_FACE);
glEnable(GL_CULL_FACE);
This is the content of my Texture class:
public int id;
public Texture(InputStream inputStream) {
ByteBuffer buf = null;
int tWidth = 0;
int tHeight = 0;
try {
PNGDecoder decoder = new PNGDecoder(inputStream);
buf = ByteBuffer.allocateDirect(4*decoder.getWidth()*decoder.getHeight());
decoder.decode(buf, decoder.getWidth()*4, PNGDecoder.TextureFormat.RGBA);
buf.rewind();
inputStream.close();
} catch (IOException exception) {
ErrorHandler.handleError("Failed to load image", exception);
}
id = glGenTextures();
glActiveTexture(id);
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tWidth, tHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
glBindTexture(GL_TEXTURE_2D, 0);
}
This is how i render:
glActiveTexture(background.id);
glBindTexture(GL_TEXTURE_2D, background.id);
glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 4*18);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindTexture(GL_TEXTURE_2D, 0);
and this is the fragment shader:
#version 330
in vec2 textureCoordinate;
out vec4 outputColor;
uniform sampler2D texture_diffuse;
void main() {
outputColor.rgb = vec3(1.0f, 1.0f, 1.0f);
outputColor += texture2D(texture_diffuse, textureCoordinate);
}
What do i do wrong? The texture coordinates passed to the shader program are 100% correct (i checked). But i still get a white quad.
Note: i use this png decoder.
EDIT:
I printed out floats for every 4 bytes to the console, and i got 0.00.00.00.0.... Doest that mean that the texture is loaded incorectly, or the informations is stored to the buffer in a different format?
Your fragment shader looks wrong - you set a white colour and add the value from the texture, so it will clamp to white. Just do something more like this
void main() {
outputColor.a = 1.0f;
outputColor.rgb = texture2D(texture_diffuse, textureCoordinate);
}
I'm having a bit of trouble rendering textures and true type fonts at the same time.
The following screenshots portray my problem:
This shows the font rendering perfectly. This was before I was using textures.
http://i.imgur.com/sUnoz.png
This shows the font after changing to textures. It goes all blurry.
http://i.imgur.com/gyhrZ.png
I'm not sure how to fix this. I've tried enabling and disabling various things, but I can't figure it out.
Here's my code:
GL initialation:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 0);
glEnable(GL_TEXTURE_2D);
Sprite Rendering:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, this.textureID);
glBegin(GL_QUADS);
{
glTexCoord2f(0, 0);
glVertex2f(0, 0);
glTexCoord2f(1, 0);
glVertex2f(this.width, 0);
glTexCoord2f(1, 1);
glVertex2f(this.width, this.height);
glTexCoord2f(0, 1);
glVertex2f(0, this.height);
}
glEnd();
glPopMatrix();
Texture Loader:
public static int loadTexture(BufferedImage image) {
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() * BYTES_PER_PIXEL); // 4 for RGBA, 3 for RGB
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 = glGenTextures(); // Generate texture ID
glBindTexture(GL_TEXTURE_2D, textureID); // Bind texture ID
// Setup wrap mode
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);
// Setup texture scaling filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Send texel data to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(),
image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Return the texture ID so we can bind it later again
return textureID;
}
I'm willing to give any more information if necessary.
Any help appreciated, thanks in advance.
I know this question was asked 6 months ago at the time of this answer, but I just want other people to know in case they run into the same problem.
I had the same problem when I was experimenting with rendering images, too, and the fix for me was to unbind the texture after I finish rendering.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, this.textureID);
glBegin(GL_QUADS);
{
glTexCoord2f(0, 0);
glVertex2f(0, 0);
glTexCoord2f(1, 0);
glVertex2f(this.width, 0);
glTexCoord2f(1, 1);
glVertex2f(this.width, this.height);
glTexCoord2f(0, 1);
glVertex2f(0, this.height);
}
glEnd();
glPopMatrix();
glBindTexture(GL_TEXTURE_2D, 0);