OpenGL 着色器无法工作
OpenGL Shader failed to work
我尝试在我的 OpenGL 项目中使用我自己的顶点着色器和片段着色器。
程序本身和着色器程序都已成功编译和链接,但顶点着色器和片段着色器均无法正常工作。我设法对着色器代码进行了一些更改,但没有任何反应,两个着色器仍然拒绝参与渲染过程。
下面是我的代码:
#include<GL\glew.h>
#include<GL\freeglut.h>
#include<iostream>
#include<fstream>
#include<string>
#include<assert.h>
using namespace std;
static GLuint VBO_handle = 0;
static GLfloat val = 1.5f;
static GLuint Unif_handle = 0;
static GLuint Program_handle = 0;
static GLuint Shader_handle = 0;
static GLuint Shader_handle2 = 0;
void init()
{
glGenBuffers(1, &VBO_handle);
glBindBuffer(GL_ARRAY_BUFFER, VBO_handle);
GLfloat vertices[] = { 0.0f, 0.8f, 0.0f, -0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f };
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}
void Rendering();
void callback_register()
{
glutDisplayFunc(Rendering);
glutIdleFunc(Rendering);
}
void Rendering()
{
glClear(GL_COLOR_BUFFER_BIT);
glUniform1f(Unif_handle, val);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
void ShaderReading()
{
Program_handle = glCreateProgram();
Shader_handle = glCreateShader(GL_VERTEX_SHADER);
std::fstream fin("vertex.vert", std::ios::in);
std::string temp;
while (fin.good())
{
string templine;
getline(fin, templine);
temp += templine;
temp.push_back('\n');
}
fin.close();
const GLchar* p[1];
p[0] = temp.c_str();
GLint Lengths[1];
Lengths[0] = temp.size();
glShaderSource(Shader_handle, 1, p, Lengths);
glCompileShader(Shader_handle);
GLint success;
glGetShaderiv(Shader_handle, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar InfoLog[1024];
glGetShaderInfoLog(Shader_handle, 1024, NULL, InfoLog);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog);
exit(1);
}
glAttachShader(Program_handle, Shader_handle);
GLint Success = 0;
GLchar ErrorLog[1024] = { 0 };
Shader_handle2 = glCreateShader(GL_FRAGMENT_SHADER);
fin.open("fragment.frag", std::ios::in);
temp.clear();
while (fin.good())
{
string templine;
getline(fin, templine);
temp += templine;
temp.push_back('\n');
}
fin.close();
p[0] = temp.c_str();
Lengths[0] = temp.size();
glShaderSource(Shader_handle2, 1, p, Lengths);
glCompileShader(Shader_handle2);
glGetShaderiv(Shader_handle2, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar InfoLog[1024];
glGetShaderInfoLog(Shader_handle2, 1024, NULL, InfoLog);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog);
exit(1);
}
glAttachShader(Program_handle, Shader_handle2);
Success = 0;
glLinkProgram(Program_handle);
glGetProgramiv(Program_handle, GL_LINK_STATUS, &Success);
if (Success == 0) {
glGetProgramInfoLog(Program_handle, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
exit(1);
}
glValidateProgram(Program_handle);
glGetProgramiv(Program_handle, GL_VALIDATE_STATUS, &Success);
if (!Success) {
glGetProgramInfoLog(Program_handle, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
exit(1);
}
glUseProgram(Shader_handle);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("6666");
callback_register();
GLenum res = glewInit();
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
init();
ShaderReading();
glutMainLoop();
return 0;
}
下面是着色器程序,确实很简单:(
顶点着色器:
#version 330
layout (location = 0) in vec3 Position;
uniform float gScale;
void main()
{
gl_Position = vec4(gScale*Position.x, Position.y, Position.z, 1.0);
}
片段着色器:
#版本 330
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
你这里有一些小错误:
glUseProgram(Shader_handle);
这实际上应该是Program_handle
。上面的代码应该只会产生一些 GL 错误并且没有任何效果。由于您处于 compatibility/legacy 配置文件中,因此您将使用固定功能管道进行绘制,并且属性 0 将为顶点位置添加别名。默认颜色为白色,因此您会看到白色三角形。
正如我已经在评论中指出的那样,您也永远不会查询制服的位置并假设它为零。由于您只使用了一件制服,这有点可能——但是,GL 规范根本不能保证这一点。你也真的应该补充一下。
我尝试在我的 OpenGL 项目中使用我自己的顶点着色器和片段着色器。 程序本身和着色器程序都已成功编译和链接,但顶点着色器和片段着色器均无法正常工作。我设法对着色器代码进行了一些更改,但没有任何反应,两个着色器仍然拒绝参与渲染过程。 下面是我的代码:
#include<GL\glew.h>
#include<GL\freeglut.h>
#include<iostream>
#include<fstream>
#include<string>
#include<assert.h>
using namespace std;
static GLuint VBO_handle = 0;
static GLfloat val = 1.5f;
static GLuint Unif_handle = 0;
static GLuint Program_handle = 0;
static GLuint Shader_handle = 0;
static GLuint Shader_handle2 = 0;
void init()
{
glGenBuffers(1, &VBO_handle);
glBindBuffer(GL_ARRAY_BUFFER, VBO_handle);
GLfloat vertices[] = { 0.0f, 0.8f, 0.0f, -0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f };
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}
void Rendering();
void callback_register()
{
glutDisplayFunc(Rendering);
glutIdleFunc(Rendering);
}
void Rendering()
{
glClear(GL_COLOR_BUFFER_BIT);
glUniform1f(Unif_handle, val);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
void ShaderReading()
{
Program_handle = glCreateProgram();
Shader_handle = glCreateShader(GL_VERTEX_SHADER);
std::fstream fin("vertex.vert", std::ios::in);
std::string temp;
while (fin.good())
{
string templine;
getline(fin, templine);
temp += templine;
temp.push_back('\n');
}
fin.close();
const GLchar* p[1];
p[0] = temp.c_str();
GLint Lengths[1];
Lengths[0] = temp.size();
glShaderSource(Shader_handle, 1, p, Lengths);
glCompileShader(Shader_handle);
GLint success;
glGetShaderiv(Shader_handle, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar InfoLog[1024];
glGetShaderInfoLog(Shader_handle, 1024, NULL, InfoLog);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog);
exit(1);
}
glAttachShader(Program_handle, Shader_handle);
GLint Success = 0;
GLchar ErrorLog[1024] = { 0 };
Shader_handle2 = glCreateShader(GL_FRAGMENT_SHADER);
fin.open("fragment.frag", std::ios::in);
temp.clear();
while (fin.good())
{
string templine;
getline(fin, templine);
temp += templine;
temp.push_back('\n');
}
fin.close();
p[0] = temp.c_str();
Lengths[0] = temp.size();
glShaderSource(Shader_handle2, 1, p, Lengths);
glCompileShader(Shader_handle2);
glGetShaderiv(Shader_handle2, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar InfoLog[1024];
glGetShaderInfoLog(Shader_handle2, 1024, NULL, InfoLog);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog);
exit(1);
}
glAttachShader(Program_handle, Shader_handle2);
Success = 0;
glLinkProgram(Program_handle);
glGetProgramiv(Program_handle, GL_LINK_STATUS, &Success);
if (Success == 0) {
glGetProgramInfoLog(Program_handle, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
exit(1);
}
glValidateProgram(Program_handle);
glGetProgramiv(Program_handle, GL_VALIDATE_STATUS, &Success);
if (!Success) {
glGetProgramInfoLog(Program_handle, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
exit(1);
}
glUseProgram(Shader_handle);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("6666");
callback_register();
GLenum res = glewInit();
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
init();
ShaderReading();
glutMainLoop();
return 0;
}
下面是着色器程序,确实很简单:( 顶点着色器:
#version 330
layout (location = 0) in vec3 Position;
uniform float gScale;
void main()
{
gl_Position = vec4(gScale*Position.x, Position.y, Position.z, 1.0);
}
片段着色器: #版本 330
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
你这里有一些小错误:
glUseProgram(Shader_handle);
这实际上应该是Program_handle
。上面的代码应该只会产生一些 GL 错误并且没有任何效果。由于您处于 compatibility/legacy 配置文件中,因此您将使用固定功能管道进行绘制,并且属性 0 将为顶点位置添加别名。默认颜色为白色,因此您会看到白色三角形。
正如我已经在评论中指出的那样,您也永远不会查询制服的位置并假设它为零。由于您只使用了一件制服,这有点可能——但是,GL 规范根本不能保证这一点。你也真的应该补充一下。