I'm using xcode to make a game with OpenGL. I have used GLUT to initialise a window. I have shaders that I wish to implement but when I try to compile them, I get two compile errors in the info log. My shaders look like this:
//FirstShader.vsh
#version 150 core
in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0);
}
//FirstShader.fsh
#version 150 core
out vec4 fragData;
void main()
{
fragData = vec4(0.0, 0.0, 1.0, 1.0);
}
I'm reading the file and compiling it with this code:
GLuint createShaderFromFile(const GLchar *path, GLenum shaderType){
GLuint shaderID = glCreateShader(shaderType);
std::ifstream fin;
fin.open(path);
if(!fin.is_open()){
fin.close();
std::cout << "Shader Not Found" << std:: endl;
return 0;
}
std::string source((std::istreambuf_iterator<GLchar>(fin)),std::istreambuf_iterator<GLchar> ());
fin.close();
const GLchar* shaderSource = source.c_str();
glShaderSource(shaderID, 1, &shaderSource, NULL);
glCompileShader(shaderID);
GLint compileStatus;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus != GL_TRUE) {
std::cout << "Shader failed to compile" << std::endl;
GLint infoLoglength;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLoglength);
GLchar* infoLog = new GLchar[infoLoglength + 1];
glGetShaderInfoLog(shaderID, infoLoglength, NULL, infoLog);
std::cout << infoLog << std::endl;
delete infoLog;
return 0;
}
return shaderID;
}
Im getting these errors:
ERROR: 0:1: '' : version '150' is not supported
ERROR: 0:1: '' : syntax error #version
My OpenGL version is 2.1 and my glsl version is 1.20. Does anybody know how I can fix this?
You can tell OSX to use a newer version of OpenGL by setting it in your pixel format when you create the context. Here is an example of how to set it up.
Or if you're using glut, I think you want glutInitContextVersion(x, y); where x and y are the major and minor version numbers. GLSL 1.5 is supported in OpenGL 3.2, I think. (And you might also want glutInitContextProfile(GLUT_CORE_PROFILE);, I think.)
I re-wrote your shaders in a way that they will actually work in GLSL 1.20.
in must be replaced with attribute in a GLSL 1.20 vertex shader
out for fragment shader output is invalid, use gl_FragColor or gl_FragData [n] instead
Declaring a vertex attribute as vec3 and then doing something like vec4 (vtx, 1.0) is completely redundant
If you declare the attribute as vec4 and give it data using fewer than 4 components GLSL will automatically fill-in the attribute's missing components this way: vec4 (0.0, 0.0, 0.0, 1.0).
Fragment Shader:
#version 120
attribute vec4 position;
void main()
{
gl_Position = position;
}
Vertex Shader:
#version 120
void main()
{
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
Of course this does not really solve your problem, because if you have a version of OS X 10.7 or newer, it supports OpenGL 3.2 and therefore GLSL 1.50 core. You need to request a core profile context for this to work, however - otherwise you will get OpenGL 2.1 and GLSL 1.20.
Related
I'm getting the following error when I try link my fragment shader,
QGLShader::compile(Fragment): 0(4) : error C0000: syntax error, unexpected '.', expecting "::" at token "."
I'm just trying to implement a simple fragment shader that sets colour to be green.
The code for my vertex shader (which is working) file name shader.vert
#version 430
in layout(location=0) vec2 position;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
}
The code for my fragment shader shader.frag
#version 430
out vec4 finalColour;
void main()
{
finalColour = vec4(0.0, 1.0, 0.0, 1.0);
}
The code that links the QGLShaderProgram mProgram
//Add Shaders
if (!mProgram.addShaderFromSourceFile(QGLShader::Vertex, "shader.vert")) {
error_msg("Vertex shader load failed");
}
if (!mProgram.addShaderFromSourceCode(QGLShader::Fragment, "testShader.frag")) {
error_msg("Fragment shader load failed");
}
if (!mProgram.link()) {
error_msg("Cannot link shaders");
}
mProgram.bind()
The second parameter of addShaderFromSourceCode(, code)
you must provide the content of file not the name of file itself
here you can put this code in a function and use it to load the file
Read whole ASCII file into C++ std::string
I'm trying to create the simplest geometry shader ever.
I have a working vertex and fragment shaders and I'm drawing triangles with
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
Vertex Shader:
// vertex shader
#version 120
attribute vec3 in_position;
uniform mat4 modelViewProjectionMatrix;
void main() {
gl_Position = modelViewProjectionMatrix * vec4(in_position, 1.0);
}
Fragment Shader:
// fragment shader
#version 120
void main() {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
Geometry Shader
//geometry shader
#version 120
#extension GL_EXT_geometry_shader4: enable
void main(void) {
for (int i = 0; i < gl_VerticesIn; i++) {
gl_Position = gl_PositionIn[i];
EmitVertex();
}
EndPrimitive();
}
my compile method which compiles all my shaders works without returning any gl_error
This is my attach and link method and this is where I get when I try to specify the output values for my shader
void attached_and_link_shaders() {
glAttachShader(programid, shaderV);
glAttachShader(programid, shaderG);
glAttachShader(programid, shaderF);
glProgramParameteriEXT(programid, GL_GEOMETRY_INPUT_TYPE_EXT, GL_TRIANGLES);
gl_error("EXT INPUT TYPE");
// error here
glProgramParameteriEXT(programid, GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLES);
gl_error("EXT OUTPUT TYPE"); // OUTPUT TYPE 1281 invalid value
glProgramParameteriEXT(programid, GL_GEOMETRY_VERTICES_OUT_EXT, 3);
gl_error("EXT VERTICES OUT");
glLinkProgram(programid);
}
Where could my problem be? any references to good geometry shader tutorials for version 120 would be helpful,
Edit my out vertices were in correct, the solution is using GL_TRIANGLE_STRIP
my problem is solved and I feel like crying
Thanks
I'm a Spannish student. Now, I'm studying OpenGL in C++.
I'm learning about it but i found a problem: the function glGetShaderiv gives me GL_FALSE (but after it the shader is used by the program without problems...)
My C++ code is:
glShaderSource(vertID, 1, &vertCode, NULL);
glGetShaderiv(vertID, GL_COMPILE_STATUS, &status);
if(!status) {
std::cout << "Error compiling vertex shader source at file '" << vertPath << "'!" << std::endl;
}
The file is found well. Data is copied well (I know it because the shader is used without problems by the OpenGL program)
My GLSL Vertex Shader Source:
#version 330 core
layout(location = 0) out vec4 color;
void main() {
color = vec4(1.0, 0.0, 0.0, 1.0);
}
Please help me! Thank you very much!
I'm trying to create a little shader for brightness and contrast of the window (that I've seen here).
I can load the file, and compile the shader successfully. But I fail to link it. My problem is that the log has no output, so I can't see what's wrong with it. How can I check the linking problem? Where can I find informations about linking failing, and check why linking can fail (I'm new to shaders).
I'm using Ubuntu 12.04.
This is the initialization code
if (GLEW_ARB_fragment_shader) {
// I enter here so I suppose that shader is enabled for
// my graphics card
std::cout << "arb shader enabled" << std::endl;
}
// Loading shader
string fragmentShaderSource;
GLint len;
std::ifstream in("/path/to/file.glsl");
fragmentShaderSource = std::string((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
len = fragmentShaderSource->size();
// I've checked the string and file seems to be loaded properly.
// Creating shader
GLint flength;
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
GLcharARB** text = new (GLcharARB*);
text[0] = (char*)fragmentShaderSource.c_str();
glShaderSourceARB(fragmentShader, 1, (const GLcharARB**) text, &flength);
// Compile shader
glCompileShaderARB(fragmentShader);
GLint compiled;
glGetObjectParameteriv(ShaderObject, GL_COMPILE_STATUS, &compiled);
if (compiled)
{
// I enter here so I suppose that compilation is ok.
std::cout << "shader compiled" << std::endl;
}
// Attaching to program
GLuint program;
program = glCreateProgram();
glAttachShader(program, fragmentShader);
// Linking
glLinkProgram(program);
// Link check
GLint linked;
glGetProgramivARB(program, GL_LINK_STATUS, &linked);
if (linked) {
std::cout << "linked" << std::endl;
} else {
// I enter here so linking is failed
std::cout << "not linked" << std::endl;
GLint blen = 0;
GLsizei slen = 0;
glGetShaderiv(program, GL_INFO_LOG_LENGTH, &blen);
// blen is equal to zero so I cannot print the log message
// because it's absent
if (blen > 1) {
GLchar* linking_log = (GLchar*) malloc(blen);
glGetProgramInfoLog(program, blen, &slen, linking_log);
glGetInfoLogARB(program, blen, &slen, linking_log);
std::cout << "compiler_log:\n" << linking_log << std::endl;
free(linking_log);
}
}
And this is the glsl code that I load
uniform float Brightness : register(C0);
uniform float Contrast : register(C1);
sampler2D Texture1Sampler : register(S0);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 pixelColor = tex2D(Texture1Sampler, uv);
pixelColor.rgb /= pixelColor.a;
// Apply contrast.
pixelColor.rgb = ((pixelColor.rgb - 0.5f) * max(Contrast, 0)) + 0.5f;
// Apply brightness.
pixelColor.rgb += Brightness;
// Return final pixel color.
pixelColor.rgb *= pixelColor.a;
return pixelColor;
}
EDIT:
I fixed log, when linking fails, I obtain following output:
Fragment info
-------------
0(1) : warning C7557: OpenGL does not allow Cg-style semantics
0(2) : warning C7557: OpenGL does not allow Cg-style semantics
0(4) : warning C7557: OpenGL does not allow Cg-style semantics
0(4) : warning C7554: OpenGL requires sampler variables to be explicitly declared as uniform
0(6) : warning C7506: OpenGL does not define the global type float4
0(6) : warning C7506: OpenGL does not define the global type float2
0(6) : warning C7557: OpenGL does not allow Cg-style semantics
0(6) : warning C7557: OpenGL does not allow Cg-style semantics
0(6) : warning C7527: OpenGL requires main to take no parameters
0(6) : warning C7530: OpenGL requires main to return void
0(9) : warning C7506: OpenGL does not define the global function tex2D
0(13) : warning C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120
0(13) : warning C7011: implicit cast from "int" to "float"
0(13) : warning C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120
EDIT2:
I've fixed fragment shader
uniform float Brightness;
uniform float Contrast;
uniform vec2 vTextureCoord;
uniform sampler2D Texture1Sampler;
void main() {
vec4 textureColor = texture2D(Texture1Sampler, vTextureCoord);
vec3 fragRGB = textureColor.rgb / textureColor.a;
fragRGB.rgb = ((fragRGB.rgb - 0.5) * max(Contrast, 0.0)) + 0.5;
fragRGB.rgb += Brightness;
fragRGB.rgb *= textureColor.a;
gl_FragColor = vec4(fragRGB, textureColor.a);
}
And I've added a basic vertex shader
attribute vec4 gl_Vertex;
void main(){
gl_Position = gl_Vertex;
}
I've added them to program. Now all compilation warning disappeared, but linking fails again.
program = glCreateProgram();
glAttachShader(program, fragmentShader); // fragment shader compiled. No warnings
glAttachShader(program, vertexShader); // vertex shader compiled. No warnings
glLinkProgram(program);
GLint linked;
glGetProgramivARB(program, GL_LINK_STATUS, &linked); // linked != GL_TRUE. Linking failed.
What I'm yet doing wrong?
You are only attaching a fragment shader and not a vertex shader. In fully programmable openGL both are required. Your code should be:
glAttachShader(program, fragmentShader);
glAttachShader(program, vertexShader);
Linking happens after shaders are attached to a program, and since both vertex and fragment shaders are required linking failed.
Moreover you are basically writing Cg in GLSL.
float4 main(float2 uv : TEXCOORD) : COLOR // These Cg semantics are not accepted in GLSL
The point is that GLSL doen't use Cg like semantics and you need to use GLSL special out variables. Check the following psudo-GLSL code.
in vec3 vertex;
//vertex shader.
void main() // write a main and output should be done using special variables
{
// output using special variables.
gl_Position = vertex;
}
//fragment shader.
uniform vec4 color;
void main() // write a main and output should be done using special variables
{
// output using special variables.
gl_FragColor = color;
}
I actually recommend that you pick a GLSL language tutorial like this one.
I have a couple of examples that I want to run on my PC. The problem is that they're written with glsl target 150 and my PC only supports version 120. I'm pretty sure that the program itself is simple enough not to require any extended functionality of OpenGL 3.1. I have found some information on what steps should be taken to transform glsl(f.e. changing in to attribute, out to varying) but it's still not compiling(is it actually possible to somehow get a meaningful error message out of this?).
original .vert
#version 150
in vec2 in_Position;
in vec3 in_Color;
out vec3 ex_Color;
void main(void) {
gl_Position = vec4(in_Position.x, in_Position.y, 0.0, 1.0);
ex_Color = in_Color;
}
original .frag
#version 150
precision highp float;
in vec3 ex_Color;
out vec4 gl_FragColor;
void main(void) {
gl_FragColor = vec4(ex_Color,1.0);
}
changed .vert
#version 120
attribute vec2 in_Position;
attribute vec3 in_Color;
varying vec3 ex_Color;
void main(void) {
gl_Position = vec4(in_Position.x, in_Position.y, 0.0, 1.0);
ex_Color = in_Color;
}
changed .frag
#version 120
precision highp float;
attribute vec3 ex_Color;
void main(void) {
gl_FragColor = vec4(ex_Color,1.0);
}
So can anyone spot a problem here?
To get the compile/link error messages, you need to use the commands glGetShaderInfoLog for shaders, and glGetProgramInfoLog for programs.
These will tell you what your particular errors are.
Just taking a stab at what the error might be, you're declaring an attribute input in the fragment shader, which I believe should be a varying. Attributes are for data->vertex shader, and varyings are for vertex shader -> fragment shader.
The glsl 120 spec also mentions that precision qualifier is "reserved for future use", so it may not be applicable to version 120. You can probably leave it out.
But you should still get familiar with the infolog functions regardless, you'll definitely need them eventually.
You can get the compile errors by retrieving the "info log":
GLuint nVertexShader, nPixelShader; // handles to objects
GLint vertCompiled, fragCompiled; // status values
GLint linked;
glCompileShader(nVertexShader);
glGetShaderiv(nVertexShader, GL_COMPILE_STATUS, &vertCompiled);
if vertCompiled (or fragCompile) == 0, do this to see why:
int infologLength = 0;
int charsWritten = 0;
glGetShaderiv(nVertexShader, GL_INFO_LOG_LENGTH, &infologLength);
if (infologLength > 0)
{
GLchar* infoLog = (GLchar *)malloc(infologLength);
if (infoLog == NULL)
{
printf( "ERROR: Could not allocate InfoLog buffer");
exit(1);
}
glGetShaderInfoLog(nVertexShader, infologLength, &charsWritten, infoLog);
printf( "Shader InfoLog:\n%s", infoLog );
free(infoLog);
}
You can do the same with linking, just check for linked == 0 and retrieve the log as above:
glLinkProgram(m_nProgram);
glGetProgramiv(m_nProgram, GL_LINK_STATUS, &linked);
precision highp float;
That is not legal in GLSL 1.20. I don't even know why it was put in the 1.50 shader anyway, since the precision qualifiers only do useful things in GLSL ES, and you can't share 1.50 shaders with GLSL ES.