【问题标题】:Setting up OpenGL program and shaders设置 OpenGL 程序和着色器
【发布时间】:2013-01-22 22:57:29
【问题描述】:

在使用了一个程序和一组顶点/片段着色器之后,我需要使用更多的程序,所以我最初没有任何参数的设置函数已经不够用了。

对于我的设置函数,我传递了 shader_program 和两个着色器源。当我尝试在我的显示方法中使用该程序时,GLuint 程序句柄为零。我目前不明白的是,为什么当我为我的着色器使用固定源时,这一切都奏效了。它可能是一个 C++ 程序并且我以错误的方式传递参数吗?我没有收到任何错误消息,但屏幕上没有呈现任何内容。

这是我用来调用着色器设置函数和函数本身的代码:

// Variables
GLuint shader_program;

const GLchar *vertex_shader =   
"#version 330\n"
""
"layout (location = 0) in vec3 in_position;"
...
"";

// In my main function, I call this to set up the shaders
installShaders(shader_program, vertex_shader, fragment_shader);

// SET-UP-METHOD
void installShaders(GLuint program_handle, const GLchar *vertex_shader_source, const GLchar *fragment_shader_source)
{
// Handles for the shader objects
GLuint   vertex_shader_name;
GLuint fragment_shader_name;

// Status values 
GLint   vertex_shader_compiled;
GLint fragment_shader_compiled;
GLint      successfully_linked;

// Generate shader names
vertex_shader_name   = glCreateShader(GL_VERTEX_SHADER);
fragment_shader_name = glCreateShader(GL_FRAGMENT_SHADER);

// Specify the sources for the shaders
glShaderSource(  vertex_shader_name, 1, (const GLchar**)&vertex_shader_source  , NULL);
glShaderSource(fragment_shader_name, 1, (const GLchar**)&fragment_shader_source, NULL);

// Compile Vertex shader and check for errors
glCompileShader(vertex_shader_name);
glGetShaderiv(vertex_shader_name, GL_COMPILE_STATUS, &vertex_shader_compiled);
printShaderInfoLog(vertex_shader_name);

// Compile Fragment shader and check for errors
glCompileShader(fragment_shader_name);
glGetShaderiv(fragment_shader_name, GL_COMPILE_STATUS, &fragment_shader_compiled);
printShaderInfoLog(fragment_shader_name);

// Exit if the shaders couldn't be compiled correctly
if(!vertex_shader_compiled || !fragment_shader_compiled)
{
    printf("Shaders were not compiled correctly!\n");
    exit(EXIT_FAILURE);
}

// Generate program name
program_handle = glCreateProgram();

// Attach shaders to the program
glAttachShader(program_handle, vertex_shader_name);
glAttachShader(program_handle, fragment_shader_name);

// Link program and check for errors
glLinkProgram(program_handle);
glGetProgramiv(program_handle, GL_LINK_STATUS, &successfully_linked);
printProgramInfoLog(program_handle);

// Exit if the program couldn't be linked correctly
if(!successfully_linked)
{
    printf("Program was not linked correctly!\n");
    exit(EXIT_FAILURE);
}

// Set up initial values of uniform variables
glUseProgram(program_handle);

location_projectionMatrix = glGetUniformLocation(program_handle, "myProjectionMatrix");
printf("Location of the uniform -->myProjectionMatrix<--- : %i\n", location_projectionMatrix);
projectionMatrix = glm::mat4(1.0f);
glUniformMatrix4fv(location_projectionMatrix, 1, GL_FALSE, glm::value_ptr(projectionMatrix));

location_modelViewMatrix = glGetUniformLocation(program_handle, "myModelViewMatrix");
printf("Location of the uniform -->myModelViewMatrix<--- : %i\n", location_modelViewMatrix);
modelViewMatrix = glm::mat4(1.0f);
glUniformMatrix4fv(location_modelViewMatrix, 1, GL_FALSE, glm::value_ptr(modelViewMatrix));

glUseProgram(0);

// Everything worked
printf("Shaders were set up correctly!\n");
}

【问题讨论】:

  • 尝试将您的program_handle 设为指针或引用(如果您使用的是 C++)。 glCreateProgram 返回的值在函数返回时丢失,因为您将 program_handle 作为值传递给函数。
  • 不客气。我想我应该这样回答。
  • 是的,也许还有一个问题...因为我对 OpenGL 和 C++ 也很陌生...我是否以“最佳”方式传递着色器源?
  • 是的。 glShaderSource 以多种方式处理源代码。如果您将着色器指定为单个以 NULL 结尾的字符串,那么您执行此操作的方式有效。
  • 嗯,你总是可以从文件中加载它们。我会构建一个类来封装着色器操作,这样程序就可以通过一次调用来创建。

标签: opengl shader


【解决方案1】:

问题在于您存储 GLSL 着色器程序名称(从 glCreateShader 返回的值)到的变量是按值传递到例程中的。因此,当函数返回时,它的值会丢失。通过引用(作为指针或作为 C++ 引用)传递值,然后在函数退出时保留该值,并且您将能够在应用程序的其他部分引用着色器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    相关资源
    最近更新 更多