- 122
- 1
- 5
Решил я сделать по гайду с ютуба сделать bloom, включил для начала только bright filter, на экране один сплошной цвет, и у меня все шейдеры с гайда работают так-же неправильно. Не могу понять что делаю не так. Буду очень благодарен, если мне кто-то поможет с решением проблемы.
Основной код где я хукаюсь:
В необходимости ImageRenderer и Fbo сомневаюсь, но пусть будут.
Основной код где я хукаюсь:
Java:
private static ImageRenderer renderer;
private static Minecraft mc;
private static int mcCopiedTexture = -1;
@SideOnly(Side.CLIENT)
public static void start(Minecraft mc1){
mc = Minecraft.getMinecraft();
renderer = new ImageRenderer(Display.getWidth()/2,Display.getHeight()/2);
if(mcCopiedTexture == -1) {
mcCopiedTexture = glGenTextures();
glBindTexture(GL11.GL_TEXTURE_2D, mcCopiedTexture);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
glTexParameteri(GL11.GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL11.GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL11.GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL11.GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
}
if(mc.thePlayer != null)
{
ShaderRegister.BRIGHT_FILTER.start();
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, mcCopiedTexture);
renderer.renderQuad();
}
}
@SideOnly(Side.CLIENT)
public static void stop(Minecraft mc)
{
ShaderRegister.BRIGHT_FILTER.stop();
renderer.cleanUp();
}
Java:
public class ImageRenderer {
private Fbo fbo;
protected ImageRenderer(int width, int height) {
this.fbo = new Fbo(width, height, Fbo.NONE);
}
protected ImageRenderer() {}
protected void renderQuad() {
if (fbo != null) {
fbo.bindFrameBuffer();
}
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
if (fbo != null) {
fbo.unbindFrameBuffer();
}
}
protected int getOutputTexture() {
return fbo.getColourTexture();
}
protected void cleanUp() {
if (fbo != null) {
fbo.cleanUp();
}
}
}
Java:
public class Fbo {
public static final int NONE = 0;
public static final int DEPTH_TEXTURE = 1;
public static final int DEPTH_RENDER_BUFFER = 2;
private final int width;
private final int height;
private int frameBuffer;
private int colourTexture;
private int depthTexture;
private int depthBuffer;
private int colourBuffer;
/**
* Creates an FBO of a specified width and height, with the desired type of
* depth buffer attachment.
*
* @param width
* - the width of the FBO.
* @param height
* - the height of the FBO.
* @param depthBufferType
* - an int indicating the type of depth buffer attachment that
* this FBO should use.
*/
public Fbo(int width, int height, int depthBufferType) {
this.width = width;
this.height = height;
initialiseFrameBuffer(depthBufferType);
}
/**
* Deletes the frame buffer and its attachments when the game closes.
*/
public void cleanUp() {
GL30.glDeleteFramebuffers(frameBuffer);
GL11.glDeleteTextures(colourTexture);
GL11.glDeleteTextures(depthTexture);
GL30.glDeleteRenderbuffers(depthBuffer);
GL30.glDeleteRenderbuffers(colourBuffer);
}
/**
* Binds the frame buffer, setting it as the current render target. Anything
* rendered after this will be rendered to this FBO, and not to the screen.
*/
public void bindFrameBuffer() {
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
}
/**
* Unbinds the frame buffer, setting the default frame buffer as the current
* render target. Anything rendered after this will be rendered to the
* screen, and not this FBO.
*/
public void unbindFrameBuffer() {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
}
/**
* Binds the current FBO to be read from (not used in tutorial 43).
*/
public void bindToRead() {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, frameBuffer);
GL11.glReadBuffer(GL30.GL_COLOR_ATTACHMENT0);
}
/**
* @return The ID of the texture containing the colour buffer of the FBO.
*/
public int getColourTexture() {
return colourTexture;
}
/**
* @return The texture containing the FBOs depth buffer.
*/
public int getDepthTexture() {
return depthTexture;
}
/**
* Creates the FBO along with a colour buffer texture attachment, and
* possibly a depth buffer.
*
* @param type
* - the type of depth buffer attachment to be attached to the
* FBO.
*/
private void initialiseFrameBuffer(int type) {
createFrameBuffer();
createTextureAttachment();
if (type == DEPTH_RENDER_BUFFER) {
createDepthBufferAttachment();
} else if (type == DEPTH_TEXTURE) {
createDepthTextureAttachment();
}
unbindFrameBuffer();
}
/**
* Creates a new frame buffer object and sets the buffer to which drawing
* will occur - colour attachment 0. This is the attachment where the colour
* buffer texture is.
*
*/
private void createFrameBuffer() {
frameBuffer = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
GL11.glDrawBuffer(GL30.GL_COLOR_ATTACHMENT0);
}
/**
* Creates a texture and sets it as the colour buffer attachment for this
* FBO.
*/
private void createTextureAttachment() {
colourTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, colourTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
(ByteBuffer) null);
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.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);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, colourTexture,
0);
}
/**
* Adds a depth buffer to the FBO in the form of a texture, which can later
* be sampled.
*/
private void createDepthTextureAttachment() {
depthTexture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT24, width, height, 0, GL11.GL_DEPTH_COMPONENT,
GL11.GL_FLOAT, (ByteBuffer) null);
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);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0);
}
/**
* Adds a depth buffer to the FBO in the form of a render buffer. This can't
* be used for sampling in the shaders.
*/
private void createDepthBufferAttachment() {
depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT24, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER,
depthBuffer);
}
}
Java:
public abstract class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
private static FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
protected static InputStream getStream(ResourceLocation location) {
try {
return Minecraft.getMinecraft().getResourceManager().getResource(location).getInputStream();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public ShaderProgram(InputStream vertexFile,InputStream fragmentFile){
vertexShaderID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
bindAttributes();
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
getAllUniformLocations();
}
protected abstract void getAllUniformLocations();
protected int getUniformLocation(String uniformName){
return GL20.glGetUniformLocation(programID,uniformName);
}
public void start(){
GL20.glUseProgram(programID);
}
public void stop(){
GL20.glUseProgram(0);
}
public void cleanUp(){
stop();
GL20.glDetachShader(programID, vertexShaderID);
GL20.glDetachShader(programID, fragmentShaderID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
GL20.glDeleteProgram(programID);
}
protected abstract void bindAttributes();
protected void bindAttribute(int attribute, String variableName){
GL20.glBindAttribLocation(programID, attribute, variableName);
}
protected void loadFloat(int location, float value){
GL20.glUniform1f(location, value);
}
protected void loadInt(int location, int value){
GL20.glUniform1i(location, value);
}
protected void loadVector(int location, Vector3f vector){
GL20.glUniform3f(location,vector.x,vector.y,vector.z);
}
protected void loadVector(int location, Vector4f vector){
GL20.glUniform4f(location,vector.x,vector.y,vector.z, vector.w);
}
protected void load2DVector(int location, Vector2f vector){
GL20.glUniform2f(location,vector.x,vector.y);
}
protected void loadBoolean(int location, boolean value){
float toLoad = 0;
if(value){
toLoad = 1;
}
GL20.glUniform1f(location, toLoad);
}
protected void loadMatrix(int location, Matrix4f matrix){
matrix.store(matrixBuffer);
matrixBuffer.flip();
GL20.glUniformMatrix4(location, false, matrixBuffer);
}
private static int loadShader(InputStream file, int type) {
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}
int shaderId = GL20.glCreateShader(type);
GL20.glShaderSource(shaderId, stringBuilder);
GL20.glCompileShader(shaderId);
if (GL20.glGetShaderi(shaderId, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.print("Could not compile " + (type == GL20.GL_FRAGMENT_SHADER ? "fragment" : "vertex") + " shader.");
System.err.println();
System.err.print(new Throwable().getStackTrace()[2].getClassName());
System.err.println();
System.err.print(GL20.glGetShaderInfoLog(shaderId, 2000));
System.err.println();
} else {
try {
System.out.print("Compiled " + Class.forName(new Throwable().getStackTrace()[2].getClassName()).getSimpleName() + "(" + (type == GL20.GL_FRAGMENT_SHADER ? "fragment" : "vertex") + ")");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String str = GL20.glGetShaderInfoLog(shaderId, 2000);
if (!str.trim().isEmpty()) {
System.out.println();
System.out.print(str);
}
System.out.println();
}
return shaderId;
}
}
Java:
public class BrightFilterShader extends ShaderProgram{
private static final ResourceLocation VERTEX_FILE = new ResourceLocation(MODID,"shaders/simpleVertex.vsh");
private static final ResourceLocation FRAGMENT_FILE = new ResourceLocation( MODID,"shaders/brightFilterFragment.frag");
public BrightFilterShader() {
super(getStream(VERTEX_FILE),getStream( FRAGMENT_FILE));
}
@Override
protected void getAllUniformLocations() {
}
@Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
}
}
C-like:
#version 150
in vec2 position;
out vec2 textureCoords;
void main(void){
gl_Position = vec4(position, 0.0, 1.0);
textureCoords = position * 0.5 + 0.5;
}
C-like:
#version 150
in vec2 textureCoords;
out vec4 out_Colour;
uniform sampler2D colourTexture;
void main(void){
vec4 colour = texture(colourTexture, textureCoords);
float brightness = (colour.r * 0.2126) + (colour.g * 0.7152) + (colour.b * 0.0722);
out_Colour = colour * brightness;
}
Последнее редактирование: