java - 纹理贴图和光照顶点着色器 ErrorJava OpenGL

标签 java opengl opengl-es fragment-shader vertex-shader

我正在尝试将纹理映射到 3D 立方体并尝试编写着色器以使其具有照明和纹理。

我试过只编写纹理着色器并且它有效。 我还尝试过仅将 3D 值设置为红色的光照着色器,并且该光照着色器也能正常工作。但是当我尝试将这两者结合起来时,我遇到了问题。 我在下面提供了我的代码,但出现错误

附加的顶点着色器未编译。无法链接着色器。

顶点着色器

#version 330 core

layout(location = 0) in vec4 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec2 VTexCoord;

out vec4 color;
out vec2 texCoord;

uniform mat4 ModelView;
uniform mat4 NormalTransform;
uniform mat4 Projection;
uniform vec4 LightPosition;
uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform float Shininess;

void main()
{
// Transform vertex position into eye coordinates
vec3 ecPosition = (ModelView * vPosition).xyz;
// Here light position is defined in eye coordinates
vec3 L = normalize( LightPosition.xyz - ecPosition );
vec3 E = normalize( -ecPosition );
vec3 H = normalize( L + E );

// Transform vertex normal into eye coordinates
vec3 N = normalize((NormalTransform *vec4(vNormal,0)).xyz);

// Compute terms in the illumination equation
vec4 ambient = AmbientProduct;

float Kd = max( dot(L, N), 0.0 );
vec4  diffuse = Kd*DiffuseProduct;

float Ks = pow( max(dot(N, H), 0.0), Shininess );
vec4  specular = Ks * SpecularProduct;

if( dot(L, N) < 0.0 ) {
specular = vec4(0.0, 0.0, 0.0, 1.0);
} 


gl_Position = Projection * ModelView * vPosition;
texCoord    = vTexCoord;
color = ambient + diffuse + specular;
color.a = 1.0;
}

片段着色器

#version 330 core

in  vec4 color;
in  vec2 texCoord;

out vec4 fColor;

uniform sampler2D tex;

void main()
{
// fColor =  texture( tex, texCoord );

vec4 t = texture( tex, texCoord );
fColor = 0.1*color + 0.9* t;
//  fColor = color*(1-t) + vec4(0.8,0.5,0.3,1)* t;
  }

编译链接

    int vShader = gl.glCreateShader(GL_VERTEX_SHADER);
    int fShader = gl.glCreateShader(GL_FRAGMENT_SHADER);

    gl.glShaderSource(vShader, 1, vSource, null);
    gl.glShaderSource(fShader, 1, fSource, null);

    gl.glCompileShader(vShader);
    gl.glCompileShader(fShader);

    program = gl.glCreateProgram();
    gl.glAttachShader(program, fShader);
    gl.glAttachShader(program, vShader);

    gl.glLinkProgram(program);

我试图获取日志文件。 enter image description here

我不确定,但问题可能是由日志文件中的异常引起的。

Internal exceptions (10 events):
Event: 0.035 Thread 0x0000000002950800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.defineClass(Ljava/lang/String;[BII)Ljava/lang/Class; name or signature does not match> (0x000000076b78cf50) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\srv„;…їЎ?
Event: 0.035 Thread 0x0000000002950800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.prefetchRead(Ljava/lang/Object;J)V name or signature does not match> (0x000000076b78d238) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\j‘ћ·¬QЉё?
Event: 0.096 Thread 0x0000000002950800 Exception <a 'java/security/PrivilegedActionException'> (0x000000076b82b230) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.096 Thread 0x0000000002950800 Exception <a 'java/security/PrivilegedActionException'> (0x000000076b82b440) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.096 Thread 0x0000000002950800 Exception <a 'java/security/PrivilegedActionException'> (0x000000076b82efe8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.096 Thread 0x0000000002950800 Exception <a 'java/security/PrivilegedActionException'> (0x000000076b82f1f8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.103 Thread 0x0000000002950800 Exception <a 'java/io/FileNotFoundException'> (0x000000076b833d80) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\jni.cpp, line 709]
Event: 0.140 Thread 0x0000000002950800 Exception <a 'java/lang/NoSuchFieldError': method resolution failed> (0x000000076bb8bcd8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\methodHandles.cpp, line 1146]
Event: 0.141 Thread 0x0000000002950800 Exception <a 'java/lang/NoSuchFieldError': method resolution failed> (0x000000076bb990a8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\methodHandles.cpp, line 1146]
Event: 0.175 Thread 0x0000000002950800 Exception <a 'java/io/FileNotFoundException'> (0x000000076bc2dc50) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u66\5298\hotspot\src\share\vm\prims\jni.cpp, line 709]

日志栈帧:

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  jogamp.opengl.gl4.GL4bcImpl.dispatch_glGetShaderInfoLog1(IILjava/lang/Object;IZLjava/lang/Object;IZJ)V+0
j  jogamp.opengl.gl4.GL4bcImpl.glGetShaderInfoLog(IILjava/nio/IntBuffer;Ljava/nio/ByteBuffer;)V+123
j  Basic.ShaderProg.loadShaders(Lcom/jogamp/opengl/GL3;)V+157
j  Basic.ShaderProg.<init>(Lcom/jogamp/opengl/GL3;Ljava/lang/String;Ljava/lang/String;)V+16
j  VCCW04$Renderer.init(Lcom/jogamp/opengl/GLAutoDrawable;)V+358
j  jogamp.opengl.GLDrawableHelper.init(Lcom/jogamp/opengl/GLEventListener;Lcom/jogamp/opengl/GLAutoDrawable;Z)V+2
j  jogamp.opengl.GLDrawableHelper.init(Lcom/jogamp/opengl/GLAutoDrawable;Z)V+81
j  jogamp.opengl.GLAutoDrawableBase$1.run()V+26
j  jogamp.opengl.GLDrawableHelper.invokeGLImpl(Lcom/jogamp/opengl/GLDrawable;Lcom/jogamp/opengl/GLContext;Ljava/lang/Runnable;Ljava/lang/Runnable;)V+197
j  jogamp.opengl.GLDrawableHelper.invokeGL(Lcom/jogamp/opengl/GLDrawable;Lcom/jogamp/opengl/GLContext;Ljava/lang/Runnable;Ljava/lang/Runnable;)V+72
j  com.jogamp.newt.opengl.GLWindow.display()V+90
j  jogamp.opengl.GLAutoDrawableBase.defaultWindowResizedOp(II)V+206
j  com.jogamp.newt.opengl.GLWindow.access$200(Lcom/jogamp/newt/opengl/GLWindow;II)V+3
j  com.jogamp.newt.opengl.GLWindow$2.windowResized(Lcom/jogamp/newt/event/WindowEvent;)V+18
j  jogamp.newt.WindowImpl.consumeWindowEvent(Lcom/jogamp/newt/event/WindowEvent;)V+234
j  jogamp.newt.WindowImpl.sendWindowEvent(I)V+14
j  jogamp.newt.WindowImpl.setVisibleActionImpl(Z)V+691
j  jogamp.newt.WindowImpl$VisibleAction.run()V+8
j  com.jogamp.common.util.RunnableTask.run()V+198
j  jogamp.newt.DefaultEDTUtil$NEDT.run()V+221
v  ~StubRoutines::call_stub

最佳答案

因为我已经发帖了,我们必须在使用 is 之前检查着色器编译链接状态。

我就是这样做的(OpenGL-ES 2.0):

    m_nVertexShader = glCreateShader(GL_VERTEX_SHADER);
    m_nPixelShader = glCreateShader(GL_FRAGMENT_SHADER);


    glShaderSource(m_nVertexShader, 1, &lpszVertexBuffer, NULL);
    glShaderSource(m_nPixelShader, 1, &lpszFragmentBuffer, NULL);

    glCompileShader(m_nVertexShader);

    int iIsOk = 0;

    glGetShaderiv(m_nVertexShader, GL_COMPILE_STATUS, &iIsOk);

    if(!iIsOk)
    {
        GLint infoLen = 0;

        glGetShaderiv(m_nVertexShader, GL_INFO_LOG_LENGTH, &infoLen);

        if(infoLen > 1)
        {
            char* infoLog = (char*)malloc(sizeof(char) * infoLen);

            glGetShaderInfoLog(m_nVertexShader, infoLen, NULL, infoLog);


            QMessageBox::warning(this, QString("Error"),
                                 QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

            free(infoLog);
        }

        glDeleteShader(m_nVertexShader);

        return;
    }

    glCompileShader(m_nPixelShader);

    glGetShaderiv(m_nPixelShader, GL_COMPILE_STATUS, &iIsOk);

    if(!iIsOk)
    {
        GLint infoLen = 0;

        glGetShaderiv(m_nPixelShader, GL_INFO_LOG_LENGTH, &infoLen);

        if(infoLen > 1)
        {
            char* infoLog = (char*)malloc(sizeof(char) * infoLen);

            glGetShaderInfoLog(m_nPixelShader, infoLen, NULL, infoLog);


            QMessageBox::warning(this, QString("Error"),
                                 QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

            free(infoLog);
        }

        glDeleteShader(m_nPixelShader);

        return;
    }

    m_nProgram = glCreateProgram();

    glAttachShader(m_nProgram, m_nVertexShader);
    glAttachShader(m_nProgram, m_nPixelShader);

    glBindAttribLocation(m_nProgram, 0, "rm_Vertex");

    glLinkProgram(m_nProgram);

    glGetProgramiv(m_nProgram, GL_LINK_STATUS, &iIsOk);

    // Fail to pass status validation
    if(!iIsOk)
    {
        GLint infoLen = 0;

        glGetProgramiv(m_nProgram, GL_INFO_LOG_LENGTH, &infoLen);

        if(infoLen > 1)
        {
            char* infoLog = (char*)malloc(sizeof(char) * infoLen);

            glGetProgramInfoLog(m_nProgram, infoLen, NULL, infoLog);


            QMessageBox::warning(this, QString("Error"),
                                 QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

            free(infoLog);
        }

        glDeleteProgram(m_nProgram);

        return;
    }

    glUseProgram(m_nProgram);

您还可以指定消息框以更具信息性的方式显示调用字符串,例如:

QMessageBox::warning(this, QString("Vertex shader compilation error."),
                                     QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

QMessageBox::warning(this, QString("Fragment shader compilation error."),
                                     QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

QMessageBox::warning(this, QString("Shader linkage error."),
                                     QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

通过这种方式,我们可以显着减少错误搜索的范围。

我突然发现了一些关于这个错误的信息,看起来像这样 JOGL2 + GLCapabilities + Windows .我认为这只是Windows问题。尝试在 Linux 操作系统上构建您的应用程序。

首先,您必须在链接前指定 rendertarget 输出。

glBindFragDataLocation(program, 0, "fColor");

关于java - 纹理贴图和光照顶点着色器 ErrorJava OpenGL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33904241/

相关文章:

java - 仔细检查包容性 OR 语句

java - Spring错误java.lang.NullPointerException

java - 如何将一个时区的本地时间保持为所有时区的时间?

c++ - OpenGL 复制顶点缓冲区对象

objective-c - OpenGL ES 使用自动引用计数进行清理

ios - 如何在 iOS 的 SceneKit 的 OpenGL SL 着色器中使用多个纹理?

java - 如何对最大到最小进行冒泡排序

java - 使用 Java 7 的 Linux 上的立体问题 - 如何在将组件添加到父组件后更改组件的 GC

opengl - 在 OpenGL 中存储和加载矩阵

Android、OpenGLES、CmdLine 工具,获取 MainDisplay 分辨率