第一个例子在OpenGL 4.0着色语言的食谱

First example in OpenGL 4.0 Shading Language Cookbook

本文关键字:语言 OpenGL 第一个      更新时间:2023-10-16

我昨天开始学习GLSL,并按照OpenGL 4.0着色语言食谱中的第一个例子一步一步地绘制三角形。

以下是我的代码:

1. shader.vert

#version 400
in vec3 VertexPosition;
in vec3 VertexColor;
out vec3 Color;
void main()
{
    Color = VertexColor;
    gl_Position = vec4(VertexPosition, 1.0);
}

2. shader.frag

#version 400
in vec3 Color;
out vec4 FragColor;
void main(){
    FragColor = vec4(Color, 1.0);
}

3. main.cpp

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowSize(500, 500);
    glutCreateWindow("Project1");
    glutDisplayFunc(render);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, 100, 0, 100);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_POINT_SMOOTH);
    // init glew
    GLenum err = glewInit();
    if (GLEW_OK != err){
        printf("Error: %sn", glewGetErrorString(err));
    }
    else{
        printf("OK: glew init.n");
    }
    // check gl version
    const GLubyte *renderer = glGetString(GL_RENDERER);
    const GLubyte *vendor = glGetString(GL_VENDOR);
    const GLubyte *version = glGetString(GL_VERSION);
    const GLubyte *glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);
    GLint major, minor;
    glGetIntegerv(GL_MAJOR_VERSION, &major);
    glGetIntegerv(GL_MINOR_VERSION, &minor);
    printf("GL Vendor   : %sn", vendor);
    printf("GL Renderer : %sn", renderer);
    printf("GL Version (string) : %sn", version);
    printf("GL Version (integer): %d.%dn", major, minor);
    printf("GLSL Version: %sn", glslVersion);
    // vertex shader
    GLuint vertShader = createAndCompileShader("shader.vert", VERTEX);
    // fragment shader
    GLuint fragShader = createAndCompileShader("shader.frag", FRAGMENT);
    // program
    GLuint programHandle = glCreateProgram();
    if (programHandle == 0)
    {
        printf("Error creating program object.n");
    }
    glAttachShader(programHandle, vertShader);
    glAttachShader(programHandle, fragShader);
    glLinkProgram(programHandle);
    GLint status;
    glGetProgramiv(programHandle, GL_LINK_STATUS, &status);
    if (GL_FALSE == status){
        printf("Failed to link shader program");
    }
    else{
        printf("OKn");
        glUseProgram(programHandle);
    }
    glutMainLoop();

    return EXIT_SUCCESS;
}

我在createAndCompileShader中创建并编译着色器,编译状态为成功。

render函数中画一个三角形

void render()
{
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
    glBegin(GL_TRIANGLES);
    glColor3f(1.0, 0.0, 0.0);
    glVertex2f(20, 20);
    glColor3f(0.0, 1.0, 0.0);
    glVertex2f(80, 20);
    glColor3f(0.0, 0.0, 1.0);
    glVertex2f(50, 80);
    glEnd();
    glPopMatrix();
    glutSwapBuffers();
}

链接状态也为success。然而,窗户上什么也没画。我确信render函数是正确的。

有什么问题吗?

如果你不绑定任何GLSL着色器,你的三角形是否可见?

  • try glDisable(GL_CULL_FACE);
  • 如果它有助于重新排序glVertex2f调用(不同的多边形缠绕)

你有什么显卡和驱动程序?

  • , OpenGL + GLSL + Windows
  • Intel几乎无法使用(特别是对于高级的东西)
  • ATI/AMD这些天通常几乎OK(最糟糕的是旧的ATI驱动程序)
  • nVidia通常没有任何问题

你不应用任何投影或模型视图矩阵在顶点着色器

  • 你的模型视图是身份的,所以这并不重要
  • 但投影不是
  • 这意味着你正在传递非转换坐标到片段着色器
  • OpenGL坐标通常在<-1,+1> 范围内
  • 和未转换的三角形不覆盖该范围
  • 因此将三角形坐标更改为该范围,例如
  • (-0.5,-0.5),(+0.5,-0.5),(0.0,+0.5)
  • ,并尝试渲染(你也可以暂时rem //gluOrtho2D(0, 100, 0, 100);只是为了确保
  • 如果它有帮助,那就是原因
  • 改变你的顶点着色器包括:gl_Position = ftransform();
  • 如果核心配置文件不再是一个选项
  • 所以你应该通过统一变量
  • 传递你的变换矩阵
  • 和乘法通常在顶点着色
  • 查看简单的GLSL引擎示例
  • 有纹理,法线贴图,3个灯,…
  • ,参见理解齐次4x4变换矩阵

[edit1]你使用的是glVertex而不是VAO,所以你应该使用compatibility配置文件

// vertex shader
#version 400 compatibility
out vec3 Color;
void main()
    {
    Color = gl_Color.rgb;
    gl_Position = ftransform();
    }
  • 应该能起作用…