Main.java:
//...
GuiTexture gui1 = new GuiTexture(loader.loadTexture("gui1.png"), new Vector2f(-0.78f, 0.9f), new Vector2f(0.2f, 0.1f));
WaterFrameBuffer fbos = new WaterFrameBuffer();
GuiTexture gui2 = new GuiTexture(fbos.getReflectionTexture(), new Vector2f(0.7f, 0.7f), new Vector2f(0.3f, 0.3f));
while(!glfwWindowShouldClose(windowHandle)) {
glClearColor(R, G, B, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
fbos.bindReflectionFrameBuffer();
scene.renderEntites();
scene.renderTerrains();
scene.renderGuis(); //RENDEROWANIE SCENY "DO TEKSTURY" NIE DZIAŁA PRAWIDŁOWO
fbos.unbindCurrentFrameBuffer();
scene.renderAll(); //RENDEROWANIE SCENY "NA EKRAN" DZIAŁA PRAWIDŁOWO
glfwSwapBuffers(windowHandle);
glfwPollEvents();
}
//...
Scene.java:
//...
public void renderEntites() {
//Dla wszystkich obiektów typu Entity:
//...
glDrawElements(GL_TRIANGLES, texturedModel.getModel().getVertexCount(), GL_UNSIGNED_INT, 0);
//...
}
public void renderTerrains() {
//Dla wszystkich obiektów typu Terrain:
//...
glDrawElements(GL_TRIANGLES, texturedModel.getModel().getVertexCount(), GL_UNSIGNED_INT, 0);
//...
}
public void renderGuis() {
//Dla wszystkich obiektów typu GuiTexture:
//...
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
glDrawArrays(GL_TRIANGLE_STRIP, 0, quad.getVertexCount());
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
//...
}
public void renderAll() {
renderEntites();
renderTerrains();
renderGuis();
}
//...
WaterFrameBuffer.java:
public class WaterFrameBuffer {
protected static final int REFLECTION_WIDTH = 320;
private static final int REFLECTION_HEIGHT = 180;
protected static final int REFRACTION_WIDTH = 1280;
private static final int REFRACTION_HEIGHT = 720;
private int reflectionFrameBuffer;
private int reflectionDepthBuffer;
private int reflectionTexture;
private int refractionFrameBuffer;
private int refractionDepthTexture;
private int refractionTexture;
public WaterFrameBuffer() {//call when loading the game
initialiseReflectionFrameBuffer();
initialiseRefractionFrameBuffer();
}
private void initialiseReflectionFrameBuffer() {
reflectionFrameBuffer = createFrameBuffer();
reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
reflectionDepthBuffer = createDepthBufferAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
Main.printlnLog(Integer.toString(glCheckFramebufferStatus(GL_FRAMEBUFFER)));
}
unbindCurrentFrameBuffer();
}
private void initialiseRefractionFrameBuffer() {
refractionFrameBuffer = createFrameBuffer();
refractionTexture = createTextureAttachment(REFRACTION_WIDTH,REFRACTION_HEIGHT);
refractionDepthTexture = createDepthTextureAttachment(REFRACTION_WIDTH,REFRACTION_HEIGHT);
unbindCurrentFrameBuffer();
}
public void bindReflectionFrameBuffer() {//call before rendering to this FBO
bindFrameBuffer(reflectionFrameBuffer,REFLECTION_WIDTH,REFLECTION_HEIGHT);
}
public void bindRefractionFrameBuffer() {//call before rendering to this FBO
bindFrameBuffer(refractionFrameBuffer,REFRACTION_WIDTH,REFRACTION_HEIGHT);
}
public void unbindCurrentFrameBuffer() {//call to switch to default frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, Main.getWindowWidth(), Main.getWindowHeight());
}
public int getReflectionTexture() {//get the resulting texture
return reflectionTexture;
}
public int getRefractionTexture() {//get the resulting texture
return refractionTexture;
}
public int getRefractionDepthTexture(){//get the resulting depth texture
return refractionDepthTexture;
}
public void clean() {
glDeleteFramebuffers(reflectionFrameBuffer);
glDeleteTextures(reflectionTexture);
glDeleteRenderbuffers(reflectionDepthBuffer);
glDeleteFramebuffers(refractionFrameBuffer);
glDeleteTextures(refractionTexture);
glDeleteTextures(refractionDepthTexture);
}
private void bindFrameBuffer(int frameBuffer, int width, int height){
glBindTexture(GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glViewport(0, 0, width, height);
}
private int createFrameBuffer() {
int frameBuffer = glGenFramebuffers();
//generate name for frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
//create the framebuffer
glDrawBuffer(GL_COLOR_ATTACHMENT0);
//indicate that we will always render to color attachment 0
return frameBuffer;
}
private int createTextureAttachment(int width, int height) {
int texture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
0, GL_RGB, GL_UNSIGNED_BYTE, (ByteBuffer) null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
return texture;
}
private int createDepthTextureAttachment(int width, int height){
int texture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, width, height,
0, GL_DEPTH_COMPONENT, GL_FLOAT, (ByteBuffer) null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
texture, 0);
return texture;
}
private int createDepthBufferAttachment(int width, int height) {
int depthBuffer = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width,
height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depthBuffer);
return depthBuffer;
}
}
Main.java - klasa główna, pętla programu
**Scene.java **- renderowanie sceny (Teren, jednostki, GUI)
WaterFrameBuffer.java - klasa skopiowana bezpośrednio z toutorialu link
Po pierwsze przepraszam za taką ilość kodu, ale bardziej nie mogłem go odchudzić. Korzystam z biblioteki LWJGL 3 i mam następujący problem:
Próbuje stworzyć coś takiego jak w tym toutorialu - link.
Jestem w tym zupełnie nowy ale z tego co zrozumiałem to na początku renderuje scenę, która następnie wykorzystywana jest jako tekstura, a dopiero potem renderuje scenę która zostanie wyświetlona na ekranie. Otrzymana na podstawie wyrenderowanej sceny tekstura(gui2), powinna zostać wyrenderowana "na ekran" (klasa GuiTexture).
W przypadku gdy w pętli while w klasie Main kod wygląda następująco:
fbos.bindReflectionFrameBuffer();
scene.renderEntites(); //OBIEKTY NIE SĄ WIDOCZNE W GUI2 - CZARNY EKRAN
scene.renderTerrains(); //OBIEKTY NIE SĄ WIDOCZNE W GUI2 - CZARNY EKRAN
scene.renderGuis(); //OBIEKTY SĄ WIDOCZNE W GUI2
fbos.unbindCurrentFrameBuffer();
scene.renderAll(); //RENDEROWANIE WSZYSTKICH ELEMENTÓW "NA EKRAN" DZIAŁA PRAWIDŁOWO
otrzymuję coś takiego:
Jak najbardziej rozumiem dlaczego gui2 wygląda jak wygląda, bo następuje tutaj zapętlenie, nie rozumiem natomiast, dlaczego obiekty typu Entity oraz Terrain nie są widoczne w gui2 skoro są prawidłowo renderowane i widoczne "na ekranie". Z góry dziękuję wszystkim za pomoc.