[Java] [OpenGL ES3.2] 混合与几何着色器,法向量可视化

提示

OpenGL ES3.2以下没有几何着色器

着色器

normal.vert

#version 320 es
layout(location=0)in vec3 a_position;
layout(location=1)in vec3 a_normal;
out VS_OUT {
vec4 normal;
} vs_out;
uniform mat4 u_projection;
uniform mat4 u_view;
uniform mat4 u_model;
void main()
{
gl_Position = u_projection * u_view * u_model * vec4(a_position,1.0f);
vs_out.normal = normalize(u_projection * transpose(inverse(u_view * u_model)) * vec4(a_normal,0.0));
}

normal.geom

#version 320 es
layout(triangles)in;
layout(line_strip,max_vertices = 6)out;
in VS_OUT {
vec4 normal;
} gs_in[];
void line(int index)
{
gl_Position = gl_in[index].gl_Position;
EmitVertex();
gl_Position = gl_in[index].gl_Position + gs_in[index].normal * 0.5;
EmitVertex();
EndPrimitive();
}
void main()
{
line(0);
line(1);
line(2);
}

normal.frag

#version 320 es
precision mediump float;
out vec4 o_color;
void main()
{
o_color = vec4(0.0,1.0,0.0,1.0);
}

代码

MySurfaceView.java

package com.Diamond.gl07;

import android.opengl.*;
import android.opengl.GLES32;
import android.opengl.GLSurfaceView;
import android.content.Context;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.EGLConfig;
import android.renderscript.Float3;
import java.io.IOException;
import android.renderscript.Float4;

public class MySurfaceView extends GLSurfaceView {
    public class MyRenderer implements GLSurfaceView.Renderer {
        public Camera camera;
        public GLES32 gl;
        public Axis axis;
        public MyObj cube;
        public Program iProgram; //光照着色器
        public Program uProgram; //普通着色器
        public Program nProgram; //法向量可视化着色器
        public Light light;
        public Plane plane;
        
        @Override
        public void onSurfaceCreated(GL10 p1, EGLConfig p2) {
            iProgram = new Program(Program.loadFromAssetsFile("illumination.vert",getResources()),Program.loadFromAssetsFile("illumination.frag",getResources()));
            uProgram = new Program(Program.loadFromAssetsFile("v.vert",getResources()),Program.loadFromAssetsFile("f.frag",getResources()));
            nProgram = new Program(Program.loadFromAssetsFile("normal.vert",getResources()),Program.loadFromAssetsFile("normal.frag",getResources()),Program.loadFromAssetsFile("normal.geom",getResources()));
            
            camera = new Camera(new Float3(0,0,2),new Float3(0,0,0),new Float3(0,1,0));
            camera.setPerspective(120.0f,0.5f,0.1f,100.0f);
            
            light = new Light();
            light.setPosition(camera.getPosition());
            
            axis = new Axis();
            
            try {
                cube = new MyObj(getResources().getAssets().open("cube.obj"));
                cube.moveZ(-0.5f); //因为我的模型在XY平面上方,所以需要挪一下位置
            } catch(IOException e) {
                e.printStackTrace();
            }
            
            plane = new Plane();
            plane.moveZ(1);
            
            gl.glEnable(gl.GL_DEPTH_TEST);
            gl.glClearColor(0.1f,0.1f,0.1f,1.0f);
        }

        @Override
        public void onSurfaceChanged(GL10 p1, int p2, int p3) {
            
        }

        @Override
        public void onDrawFrame(GL10 p1) {
            gl.glClear(gl.GL_COLOR_BUFFER_BIT|gl.GL_DEPTH_BUFFER_BIT);
            
            uProgram.useProgram();
            uProgram.setUniform("u_projection",camera.getProjectionMatrix());
            uProgram.setUniform("u_view",camera.getViewMatrix());
            axis.draw(uProgram);
            
            iProgram.useProgram();
            iProgram.setUniform("u_projection",camera.getProjectionMatrix());
            iProgram.setUniform("u_view",camera.getViewMatrix());
            iProgram.setUniform("u_color",new Float4(0,0,1,1));
            iProgram.setUniform("u_lightcolor",light.color);
            iProgram.setUniform("u_lightposition",light.getPosition());
            iProgram.setUniform("u_cameraposition",camera.getPosition());
            iProgram.setUniform("u_intensity",light.intensity);
            cube.draw(iProgram);
            
            nProgram.useProgram();
            nProgram.setUniform("u_projection",camera.getProjectionMatrix());
            nProgram.setUniform("u_view",camera.getViewMatrix());
            cube.draw(nProgram);
            
            uProgram.useProgram();
            uProgram.setUniform("u_projection",camera.getProjectionMatrix());
            uProgram.setUniform("u_view",camera.getViewMatrix());
            plane.draw(uProgram);
        }
    }
    
    private MyRenderer renderer;
    public MySurfaceView(Context context) {
        super(context);
        this.setEGLContextClientVersion(3);
        renderer = new MyRenderer();
        this.setRenderer(renderer);
        this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }
}

Plane.java

package com.Diamond.gl07;

import android.opengl.GLES32;

public class Plane extends MyObject {
    public int VAO;
    public GLES32 gl;
    
    public Plane() {
        float[] vertices = new float[]{
            -1,1,0,
            -1,-1,0,
            1,1,0,
            1,-1,0
        };
        
        float[] colors = new float[]{
            1,0,0,0.5f,
            0,1,0,0.5f,
            0,0,1,0.5f,
            1,1,0,0.5f
        };
        
        VAO = BufferUtil.genVertexArray();
        BufferUtil.bindVertexArray(VAO);
        int vbo1 = BufferUtil.bindVBO(vertices,gl.GL_STATIC_DRAW,0,3);
        int vbo2 = BufferUtil.bindVBO(colors,gl.GL_STATIC_DRAW,1,4);
        BufferUtil.bindVertexArray();
        BufferUtil.deleteBuffers(new int[]{vbo1,vbo2});
        BufferUtil.bindBuffer(gl.GL_ARRAY_BUFFER);
    }
    
    public Plane draw(Program program) {
        program.setUniform("u_model",getModelMatrixArray());
        BufferUtil.bindVertexArray(VAO);
        //打开混合
        gl.glEnable(gl.GL_BLEND);
        //设置混合参数
        gl.glBlendFunc(gl.GL_SRC_ALPHA,gl.GL_ONE_MINUS_SRC_ALPHA);
        //绘制平面
        gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,0,4);
        //关闭混合
        gl.glDisable(gl.GL_BLEND);
        BufferUtil.bindVertexArray();
        return this;
    }
}

效果

在这里插入图片描述
在这里插入图片描述

参考

混合-LearnOpeenGL CN
几何着色器-LearnOpenGL CN

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值