- 7,099
- 324
- 1,510
Хочу сделать следующую вещь:
рендерить какой-нить контент во фреймбуфер и потом юзать этот фреймбуфер в качестве текстуры для другого полигона.
Есть такой фрагмент кода, который производит рендер во фреймбуфер
Результат:
1) текст рисуется глифами галактического алфавита(зачарования), хотя я не включал эту опцию
2) фиолетового полигона не видно
Если убрать строчку рендера текста, то полигон становится виден.
Эта штука рендерит во фреймбуфер, а потом использует его как текстуру, чтобы нарисовать квад размером с фреймбуфер.
Если рендерить сразу на экран, то эффект 2) сохраняется, а эффект 1) - нет.
Как это работает? Почему оно так работает? Как это исправить?
Полный код:
рендерить какой-нить контент во фреймбуфер и потом юзать этот фреймбуфер в качестве текстуры для другого полигона.
Есть такой фрагмент кода, который производит рендер во фреймбуфер
Scala:
def drawPageContainerContent(): Unit = {
mc.fontRenderer.drawString("Testlol", 100, 100, 0xff00ff)
val buffer = Tessellator.getInstance.getBuffer
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR)
buffer.pos(0, 0, 0).color(255, 0, 255, 255).endVertex()
buffer.pos(0, 50, 0).color(255, 0, 255, 255).endVertex()
buffer.pos(50, 50, 0).color(255, 0, 255, 255).endVertex()
buffer.pos(50, 0, 0).color(255, 0, 255, 255).endVertex()
Tessellator.getInstance.draw()
}
1) текст рисуется глифами галактического алфавита(зачарования), хотя я не включал эту опцию
2) фиолетового полигона не видно
Если убрать строчку рендера текста, то полигон становится виден.
Эта штука рендерит во фреймбуфер, а потом использует его как текстуру, чтобы нарисовать квад размером с фреймбуфер.
Если рендерить сразу на экран, то эффект 2) сохраняется, а эффект 1) - нет.
Как это работает? Почему оно так работает? Как это исправить?
Полный код:
Scala:
package ru.mousecray.endmagic.client.render.book
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
import net.minecraft.client.renderer.{GlStateManager, Tessellator}
import net.minecraft.client.shader.Framebuffer
import net.minecraft.util.ResourceLocation
import org.lwjgl.opengl.GL11
import ru.mousecray.endmagic.EM
import ru.mousecray.endmagic.api.embook.PageContainer
object PageRenderer {
lazy val mc = Minecraft.getMinecraft
def drawPageTo(pageContainer: PageContainer, framebuffer: Framebuffer): Unit = {
GlStateManager.enableTexture2D()
GlStateManager.disableLighting()
GlStateManager.enableAlpha()
GlStateManager.enableBlend()
GlStateManager.disableDepth()
framebuffer.bindFramebuffer(true)
saveMatrices()
identityMatrices()
setupProjectionArea()
drawPageContainerBackRect()
drawPageContainerContent()
restoreMatrices()
mc.getFramebuffer.bindFramebuffer(true)
}
def drawPageContainerContent(): Unit = {
mc.fontRenderer.drawString("Testlol", 100, 100, 0xff00ff)
val buffer = Tessellator.getInstance.getBuffer
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR)
buffer.pos(0, 0, 0).color(255, 0, 255, 255).endVertex()
buffer.pos(0, 50, 0).color(255, 0, 255, 255).endVertex()
buffer.pos(50, 50, 0).color(255, 0, 255, 255).endVertex()
buffer.pos(50, 0, 0).color(255, 0, 255, 255).endVertex()
Tessellator.getInstance.draw()
}
val w = 260
val h = 208
val tw = 128
val th = 64
val uw = 20
val vh = 16
val u0 = 48d
val v0 = 20d
val u1 = u0 + uw
val v1 = v0 + vh
def drawPageContainerBackRect(): Unit = {
Minecraft.getMinecraft.getTextureManager.bindTexture(new ResourceLocation(EM.ID, "textures/models/book/em_book.png"))
val buffer = Tessellator.getInstance.getBuffer
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR)
buffer.pos(0, 0, 0).tex(u0 / tw, v0 / th).color(255, 255, 255, 255).endVertex()
buffer.pos(0, h, 0).tex(u0 / tw, v1 / th).color(255, 255, 255, 255).endVertex()
buffer.pos(w, h, 0).tex(u1 / tw, v1 / th).color(255, 255, 255, 255).endVertex()
buffer.pos(w, 0, 0).tex(u1 / tw, v0 / th).color(255, 255, 255, 255).endVertex()
Tessellator.getInstance.draw()
}
private def setupProjectionArea(): Unit = {
GL11.glOrtho(0, w, h, 0, -10, 10)
}
private def identityMatrices(): Unit = {
GL11.glMatrixMode(GL11.GL_MODELVIEW)
GL11.glLoadIdentity()
GL11.glMatrixMode(GL11.GL_PROJECTION)
GL11.glLoadIdentity()
}
private def saveMatrices(): Unit = {
GL11.glMatrixMode(GL11.GL_MODELVIEW)
GL11.glPushMatrix()
GL11.glMatrixMode(GL11.GL_PROJECTION)
GL11.glPushMatrix()
}
private def restoreMatrices(): Unit = {
GL11.glMatrixMode(GL11.GL_PROJECTION)
GL11.glPopMatrix()
GL11.glMatrixMode(GL11.GL_MODELVIEW)
GL11.glPopMatrix()
}
}
Scala:
package ru.mousecray.endmagic.client.render.book
import net.minecraft.client.shader.Framebuffer
import ru.mousecray.endmagic.api.embook.PageContainer
import ru.mousecray.endmagic.client.render.book.Refs._
import ru.mousecray.endmagic.client.render.book.PageRenderer._
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
object PageTextureHolder {
def getTexture(pageContainer: PageContainer): Framebuffer = {
textures.getOrElseUpdate(pageContainer, {
if (freeTextures.isEmpty)
throw new IllegalStateException("Attempt to use more that 4 framebuffers")
val fb = freeTextures.remove(freeTextures.size - 1)
drawPageTo(pageContainer, fb)
fb
})
}
def freeTexture(pageContainer: PageContainer): Unit = {
textures.get(pageContainer).foreach {
fb =>
textures -= pageContainer
freeTextures += fb
}
}
private val textures = new mutable.HashMap[PageContainer, Framebuffer]
private lazy val freeTextures = {
val r = new ArrayBuffer[Framebuffer]
for (i <- 1 to 4)
r += new Framebuffer(pageContainerWidth, pageHeight, false)
r
}
}
Java:
package ru.mousecray.endmagic.client.render.book;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.opengl.GL11;
import ru.mousecray.endmagic.EM;
import ru.mousecray.endmagic.api.embook.BookApi;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
@Mod.EventBusSubscriber(modid = EM.ID)
public class TestOverlay {
@SubscribeEvent
public static void onRenderTest(RenderGameOverlayEvent.Pre event) {
PageTextureHolder.freeTexture(BookApi.mainChapter());
Framebuffer texture = PageTextureHolder.getTexture(BookApi.mainChapter());
drawPageContainerRect(texture);
//PageRenderer.drawPageContainerBackRect();
//PageRenderer.drawPageContainerContent();
//drawPageContainerRectOriginal();
}
static int x = 10;
static int y = 10;
static int w = 260;
static int h = 208;
private static void drawPageContainerRect(Framebuffer framebuffer) {
int current = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
framebuffer.bindFramebufferTexture();
{
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
buffer.pos(x, y, 0).tex(0, 1).color(255, 255, 255, 255).endVertex();
buffer.pos(x, y + h, 0).tex(0, 0).color(255, 255, 255, 255).endVertex();
buffer.pos(x + w, y + h, 0).tex(1, 0).color(255, 255, 255, 255).endVertex();
buffer.pos(x + w, y, 0).tex(1, 1).color(255, 255, 255, 255).endVertex();
Tessellator.getInstance().draw();
}
framebuffer.unbindFramebufferTexture();
{
//framebuffer.framebufferClear();
//mc.getFramebuffer().bindFramebuffer(true);
GL11.glBindTexture(GL_TEXTURE_2D, current);
}
}
private static void drawPageContainerRectOriginal() {
int current = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
//framebuffer.bindFramebufferTexture();
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation(EM.ID, "textures/models/book/page.png"));
{
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
buffer.pos(x + w + 10, y, 0).tex(0, 0).color(255, 255, 255, 255).endVertex();
buffer.pos(x + w + 10, y + h, 0).tex(0, 1).color(255, 255, 255, 255).endVertex();
buffer.pos(x + w + w + 10, y + h, 0).tex(1, 1).color(255, 255, 255, 255).endVertex();
buffer.pos(x + w + w + 10, y, 0).tex(1, 0).color(255, 255, 255, 255).endVertex();
Tessellator.getInstance().draw();
}
//framebuffer.unbindFramebufferTexture();
{
//framebuffer.framebufferClear();
//mc.getFramebuffer().bindFramebuffer(true);
GL11.glBindTexture(GL_TEXTURE_2D, current);
}
}
}