我正在尝试运行一个使用着色器的程序。在我提出的另一个问题中,我发现我将固定管道函数与更新的东西(来自OpenGL 2.0)混合在一起,所以我尝试删除所有“旧东西”,比如glMatrixMode,但我不确定是否正确。毫无疑问,我还删除了像glLightfv这样的调用,如果我使用可编程管道,我不确定它们是否被允许。
这是主要代码:
#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <vector>
#include "utility.hpp"
#include "program.hpp"
GLfloat width=600, height=800;
Program* program_ref;
void init()
{
glewInit();
Shader vertex_shader= Shader("vertex_shader",GL_VERTEX_SHADER);
// This just reads the file "vertex_shader", creates the shader and compiles it
Shader geometry_shader= Shader(); // This means that the shader is empty
// So the program class will be enough smart to recognize it and don't attach it
Shader fragment_shader= Shader("fragment_shader",GL_FRAGMENT_SHADER);
program_ref= new Program(vertex_shader,geometry_shader,fragment_shader);
// This creates a program, attaches the shaders to it, links and uses it
}
void display()
{
vector<GLfloat> quad{-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5};
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2,GL_FLOAT,0,quad.data());
glDrawArrays(GL_QUADS,0,4);
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
cout << glGetError() << endl;
}
void reshape(int w, int h)
{
width=w;
height=h;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("test");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
init();
glewInit();
glutMainLoop();
return 0;
}
(可选类查看,在我写的评论中程序和着色器的行为如何)
shader.hpp:
#ifndef shader_hpp
#define shader_hpp
#include "utility.hpp"
#include "shader.hpp"
#include <fstream>
#define MAX_SIZE (size_t)1.0e5
class Shader
{
private:
GLuint id;
GLenum type;
bool null;
public:
Shader()
{
id=-1;
type= -1;
null= true;
}
Shader(const string& filename,GLenum type)
{
GLchar* data= new GLchar[MAX_SIZE];
streamsize count;
this->type= type;
ifstream is;
is.open(filename);
is.read(data,MAX_SIZE);
count= is.gcount();
is.close();
id=glCreateShader(type);
glShaderSource(id,1,(const GLchar**)&data,&count);
glCompileShader(id);
delete[] data;
null= false;
}
GLuint getId() const
{
return id;
}
GLenum getType() const
{
return type;
}
bool isNull() const
{
return null;
}
};
#endif
program.hpp:
#ifndef program_hpp
#define program_hpp
#include "utility.hpp"
#include "shader.hpp"
class Program
{
private:
GLuint id;
public:
Program(const Shader& vertex_shader, const Shader& geometry_shader, const Shader& fragment_shader)
{
id= glCreateProgram();
if(!vertex_shader.isNull())
{
glAttachShader(id,vertex_shader.getId());
}
if(!geometry_shader.isNull())
{
glAttachShader(id,geometry_shader.getId());
}
if(!fragment_shader.isNull())
{
glAttachShader(id,fragment_shader.getId());
}
glLinkProgram(id);
glUseProgram(id);
}
GLuint getId()
{
return id;
}
};
#endif
当使用glew编译着色器并将它们附加到程序时,有两个类只是为了简化一切。
问题如下:如果我只附加顶点着色器而不是片段着色器,一切都很好,我看到用正确的颜色绘制的四边形(红色,因为在下面的顶点着色器中我会将颜色设置为红色)。如果我同时附加片段着色器,我看到四边形是白色的。我还试图看看哪里不对,我打印了glGetError()的结果。如果我包含片段着色器,我会得到错误1282,如果我不包含它,我不会得到任何错误(0)。
顶点着色器:
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = vec4(1,0,0,1);
// The only relevant thing I do is to set the color to red
// I see the quad red if I attach only the vertex shader and not the fragment shader
gl_TexCoord[0] = gl_MultiTexCoord0;
}
片段着色器:
void main()
{
gl_fragColor= gl_Color;
}
试一试:
#include <GL/glew.h>
#include <GL/glut.h>
#include <vector>
#include <iostream>
using namespace std;
void CheckStatus( GLuint obj )
{
GLint status = GL_FALSE, len = 10;
if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
if( glIsShader(obj) ) glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
if( glIsProgram(obj) ) glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
vector< char > log( len, 'X' );
if( glIsShader(obj) ) glGetShaderInfoLog( obj, len, NULL, &log[0] );
if( glIsProgram(obj) ) glGetProgramInfoLog( obj, len, NULL, &log[0] );
cerr << &log[0] << endl;
exit( -1 );
}
GLuint LoadShader( GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader );
return shader;
}
GLuint LoadProgram( const char* vert, const char* geom, const char* frag )
{
GLuint program = glCreateProgram();
if( vert ) glAttachShader( program, LoadShader( GL_VERTEX_SHADER, vert ) );
if( geom ) glAttachShader( program, LoadShader( GL_GEOMETRY_SHADER, geom ) );
if( frag ) glAttachShader( program, LoadShader( GL_FRAGMENT_SHADER, frag ) );
glLinkProgram( program );
CheckStatus( program );
return program;
}
#define GLSL(version, shader) "#version " #version "\n" #shader
const GLchar* vert = GLSL
(
120,
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = vec4(1.0,0.0,0.0,1.0);
// The only relevant thing I do is to set the color to red
// I see the quad red if I attach only the vertex shader and not the fragment shader
gl_TexCoord[0] = gl_MultiTexCoord0;
}
);
const GLchar* frag = GLSL
(
120,
void main()
{
gl_FragColor= gl_Color;
}
);
void display()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
static GLuint prog = LoadProgram( vert, NULL, frag );
glUseProgram( prog );
glEnableClientState(GL_VERTEX_ARRAY);
GLfloat quad[] = {-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5};
glVertexPointer(2,GL_FLOAT,0,quad);
glDrawArrays(GL_QUADS,0,4);
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("test");
glutDisplayFunc(display);
glewInit();
glutMainLoop();
return 0;
}
正如安东尼·布洛姆指出的那样gl_fragColor应该是gl_FragColor
。小写的f
阻塞了我系统上的GLSL编译器。
问题内容: Go编译器抱怨我的代码将切片附加到切片。以下是相关摘录: 该行生成以下编译器消息: 我知道,根据Go Blog帖子中 标题为Append:the Built-in function 一节下的示例,将切片追加到切片会很好。 问题答案: 您需要使用: 另外,还请格式化您的代码:) 您还应该阅读Wiki上的Slice Tricks。
假设我遇到这样的问题:现在我有一个帧缓冲区,一个纹理只包含一个颜色组件(例如,GL_RED)已经绑定到它。碎片着色器会是什么样子?我想答案是: ...浮出ex_color; 颜色=。。。; 我的问题来了:着色器会自动检测帧缓冲区的格式并向其写入值吗?如果片段着色器输出浮点值但帧缓冲区格式GL_RGBA怎么办? 顺便问一下,创建只有一个组件的纹理的正确方法是什么?我阅读了g-truc的示例,其示例如
在一个简单的hello world OpenGL程序中,它只是在窗口上绘制一个静态三角形,当我将三角形的3个顶点设置为红色、绿色和蓝色时,三角形将填充渐变。 但是当我使用这样的着色器时: 顶点着色器: 其中属性和来自顶点缓冲区,通过的调用传递。 片段着色器: 三角形仍然充满了梯度,问题来了: 如果顶点着色器是按顶点计算的,则应为的每个实例指定顶点的颜色。顶点颜色应为红色、绿色或蓝色,如顶点缓冲区中
片段着色器调用每个需要渲染的像素。我们将开发一个红色透镜,它将会增加图片的红色通道的值。 配置场景(Setting up the scene) 首先我们配置我们的场景,在区域中央使用一个网格显示我们的源图片(source image)。 import QtQuick 2.0 Rectangle { width: 480; height: 240 color: '#1e1e1e'
如何使用片段着色器绘制一条线或一条曲线? 我有一个程序,根据用户指定的一组顶点计算贝塞尔曲线。在早期,我非常简单,只需在应用程序端处理每个顶点,就可以根据三次贝塞尔曲线方程生成一组插值点: ... 然后将所有处理过的顶点存储到GL_VERTEX_数组中,以便使用glDrawArrays(GL_LINE_STRIP,0,myArraySize)绘制。虽然解决方案很简单,但此实现的时间复杂度为O(n^