图像不可见

时间:2013-09-15 11:00:52

标签: java opengl shader lwjgl

我一直在尝试使用38leinaD code显示图像。

这是一个略微修改的版本,我尝试显示图像:

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.*;

public class DistortionCorrection {

    public enum Eye {
        Left, Right
    };

    protected int shader=0;
    protected int vertShader=0;
    protected int fragShader=0;

    protected int colorTextureID;
    protected int framebufferID;
    protected int depthRenderBufferID;

    private int LensCenterLocation;
    private int ScreenCenterLocation;
    private int ScaleLocation;
    private int ScaleInLocation;
    private int HmdWarpParamLocation;

    // renderDistortedEye
    public static float K0 = 1.0f;
    public static float K1 = 0.22f;
    public static float K2 = 0.24f;
    public static float K3 = 0.0f;

    // Added
    BufferedImage panda;
    private static final int BYTES_PER_PIXEL = 4;
    int pandaID;

    private final static String VERTEX_SHADER_SOURCE =
            "void main() {\n" +
                    "   gl_TexCoord[0] = gl_MultiTexCoord0;\n" +
                    "   gl_Position = gl_Vertex;\n" +
                    "}";

    private final static String FRAGMENT_SHADER_SOURCE =
            "uniform sampler2D tex;\n" +
                    "uniform vec2 LensCenter;\n" +
                    "uniform vec2 ScreenCenter;\n" +
                    "uniform vec2 Scale;\n" +
                    "uniform vec2 ScaleIn;\n" +
                    "uniform vec4 HmdWarpParam;\n" +
                    "\n" +
                    "vec2 HmdWarp(vec2 texIn)\n" +
                    "{\n" +
                    "   vec2 theta = (texIn - LensCenter) * ScaleIn;\n" +
                    "   float  rSq= theta.x * theta.x + theta.y * theta.y;\n" +
                    "   vec2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + " +
                    "           HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n" +
                    "   return LensCenter + Scale * theta1;\n" +
                    "}\n" +
                    "\n" +
                    "\n" +
                    "\n" +
                    "void main()\n" +
                    "{\n" +
                    "   vec2 tc = HmdWarp(gl_TexCoord[0].xy);\n" +
                    "   if (any(notEqual(clamp(tc, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25, 0.5)) - tc, vec2(0.0, 0.0))))\n" +
                    "       gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" +
                    "   else\n" +
                    "       gl_FragColor = texture2D(tex, tc);\n" +
                    "}";

    public DistortionCorrection(int screenWidth, int screenHeight) {
        initShaders(VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE);
        initFBO(screenWidth, screenHeight);

        // Added
        glOrtho(0, Display.getWidth(), Display.getHeight(), 0, -1, 1);
        try {
            panda = ImageIO.read(new File("/Users/webstorms/Desktop/panda.jpg"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        glEnable(GL_TEXTURE_2D);
        pandaID = loadTexture(panda);
        glBindTexture(GL_TEXTURE_2D, pandaID);
        // Added end

        Util.checkGLError();

        LensCenterLocation = glGetUniformLocation(shader, "LensCenter");
        ScreenCenterLocation = glGetUniformLocation(shader, "ScreenCenter");
        ScaleLocation = glGetUniformLocation(shader, "Scale");
        ScaleInLocation = glGetUniformLocation(shader, "ScaleIn");
        HmdWarpParamLocation = glGetUniformLocation(shader, "HmdWarpParam");
        System.out.println(FRAGMENT_SHADER_SOURCE);
        Util.checkGLError();
    }

    private void initFBO(int screenWidth, int screenHeight) {
        framebufferID = glGenFramebuffers();                                                                               
        colorTextureID = glGenTextures();                                                                                               
        depthRenderBufferID = glGenRenderbuffers();                                                                 

        glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);                                               

        // initialize color texture
        glBindTexture(GL_TEXTURE_2D, colorTextureID);                                                                 
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);                               
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, screenWidth, screenHeight, 0,GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);
        //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, colorTextureID, 0);

        // initialize depth renderbuffer
        glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBufferID);                               
        glRenderbufferStorage(GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT24, screenWidth, screenHeight);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER, depthRenderBufferID);

        glBindFramebuffer(GL_FRAMEBUFFER, 0);                                                                   
    }

    public void beginOffScreenRenderPass() {

        glBindTexture(GL_TEXTURE_2D, 0);         
        Util.checkGLError();
        glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
        Util.checkGLError();
    }

    public void endOffScreenRenderPass() {

    }

    public void renderToScreen() {
        Util.checkGLError();
        glUseProgram(shader);
        Util.checkGLError();


        glEnable(GL_TEXTURE_2D);   
        glDisable(GL_DEPTH_TEST);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);                                   

        glClearColor (1.0f, 0.0f, 0.0f, 0.5f);
        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBindTexture(GL_TEXTURE_2D, colorTextureID);   

        renderDistortedEye(Eye.Left, 0.0f, 0.0f, 0.5f, 1.0f);
        renderDistortedEye(Eye.Right, 0.5f, 0.0f, 0.5f, 1.0f);

        glUseProgram(0);
        glEnable(GL_DEPTH_TEST);

    }

    public void renderDistortedEye(Eye eye, float x, float y, float w, float h) {
        float as = w/h;

        float scaleFactor = 1.0f;
        Util.checkGLError();

        float DistortionXCenterOffset;
        if (eye == Eye.Left) {
            DistortionXCenterOffset = 0.25f;
        }
        else {
            DistortionXCenterOffset = -0.25f;
        }

        glUniform2f(LensCenterLocation, x + (w + DistortionXCenterOffset * 0.5f)*0.5f, y + h*0.5f);
        glUniform2f(ScreenCenterLocation, x + w*0.5f, y + h*0.5f);
        glUniform2f(ScaleLocation, (w/2.0f) * scaleFactor, (h/2.0f) * scaleFactor * as);;
        glUniform2f(ScaleInLocation, (2.0f/w), (2.0f/h) / as);

        glUniform4f(HmdWarpParamLocation, K0, K1, K2, K3);

        if (eye == Eye.Left) {
            glBegin(GL_TRIANGLE_STRIP);
            glTexCoord2f(0.0f, 0.0f);   glVertex2f(-1.0f, -1.0f);
            glTexCoord2f(0.5f, 0.0f);   glVertex2f(0.0f, -1.0f);
            glTexCoord2f(0.0f, 1.0f);   glVertex2f(-1.0f, 1.0f);
            glTexCoord2f(0.5f, 1.0f);   glVertex2f(0.0f, 1.0f);
            glEnd();
        }
        else {
            glBegin(GL_TRIANGLE_STRIP);
            glTexCoord2f(0.5f, 0.0f);   glVertex2f(0.0f, -1.0f);
            glTexCoord2f(1.0f, 0.0f);   glVertex2f(1.0f, -1.0f);
            glTexCoord2f(0.5f, 1.0f);   glVertex2f(0.0f, 1.0f);
            glTexCoord2f(1.0f, 1.0f);   glVertex2f(1.0f, 1.0f);
            glEnd();           
        }
    }

    protected void initShaders(String vertexShader, String fragmentShader) {
        shader=glCreateProgram();

        vertShader=createVertShader(vertexShader);
        fragShader=createFragShader(fragmentShader);

        glAttachShader(shader, vertShader);
        glAttachShader(shader, fragShader);

        glLinkProgram(shader);
        glValidateProgram(shader);
    }

    private int createVertShader(String vertexCode){
        vertShader=glCreateShader(GL_VERTEX_SHADER);

        if (vertShader==0) {
            return 0;
        }

        glShaderSource(vertShader, vertexCode);
        glCompileShader(vertShader);

        return vertShader;
    }

    private int createFragShader(String fragCode){

        fragShader = glCreateShader(GL_FRAGMENT_SHADER);
        if (fragShader==0) {
            return 0;
        }
        glShaderSource(fragShader, fragCode);
        glCompileShader(fragShader);

        return fragShader;
    }

    public static void main(String[] args) {

        try {
            DisplayMode displayMode = Display.getDesktopDisplayMode();
            Display.setDisplayMode(displayMode);
            Display.setTitle("Barrel Distorion Shader");
            Display.setFullscreen(true);
            PixelFormat pixelFormat = new PixelFormat(8, 8, 8);
            Display.create(pixelFormat);
        } catch (LWJGLException e) {
            e.printStackTrace();
        }

        DistortionCorrection shader = new DistortionCorrection(640, 400);

        while (!Display.isCloseRequested()) {
            if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
                System.exit(0);
            }
            shader.beginOffScreenRenderPass();

            glDisable(GL_DEPTH_TEST);
            glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
        //  glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();

            // Content

            // Added
            //   glPushMatrix();
            //    glTranslatef(100, 100, 0);
            glBegin(GL_QUADS);
            {
                glTexCoord2f(0, 0);
                glVertex2f(0, 0);

                glTexCoord2f(1, 0);
                glVertex2f(Display.getWidth(), 0);

                glTexCoord2f(1, 1);
                glVertex2f(Display.getWidth(), Display.getHeight());

                glTexCoord2f(0, 1);
                glVertex2f(0, Display.getHeight());
            }
            glEnd();
           //  glPopMatrix();
             // Added end

            /*
            glBegin(GL_LINES);
            glColor3f(1.0f, 1.0f, 0.0f);
            for (int i=0; i<20; i++) {
                glVertex2f(-1.0f, -1.0f + 0.1f * i);
                glVertex2f(1.0f, -1.0f + 0.1f * i);
            }
            for (int i=0; i<20; i++) {
                glVertex2f(-1.0f + 0.1f * i, -1.0f);
                glVertex2f(-1.0f + 0.1f * i, 1.0f);
            }
            glEnd(); */

            shader.endOffScreenRenderPass();
            shader.renderToScreen();

            Display.sync(60);
            Display.update();
        }
    }
     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;
       }

}

1 个答案:

答案 0 :(得分:0)

根据您的意见,我对您的代码进行了一些可能实现您想要的更改:

//
// This polygon is wound Clockwise instead of Counter-Clockwise; when you start
//   using projection matrices and face culling this is a concept you will need
//     to understand. 
//
// Counter-Clockwise is the preferred winding order in OpenGL, by the way - I
//   just wanted to show this to you for future reference.
//
glBegin (GL_QUADS);
{
  glTexCoord2f ( 0.0f,  0.0f);
  glVertex2f   (-1.0f, -1.0f); // Bottom-left

  glTexCoord2f ( 0.0f,  1.0f);
  glVertex2f   (-1.0f,  1.0f); // Top-Left

  glTexCoord2f ( 1.0f,  1.0f);
  glVertex2f   ( 1.0f,  1.0f); // Top-Right

  glTexCoord2f ( 1.0f,  0.0f);
  glVertex2f   ( 1.0f, -1.0f); // Bottom-Right
}
glEnd ();

此代码使用规范化设备坐标,这样您就不必知道窗口的尺寸,以便创建填充整个屏幕的四边形(更重要的是不需要非标识投影矩阵)

我不知道这是否会解决你的整个问题,但这绝对是一个开始。