I am trying to use GLSL with openGL 2.0.
Can anyone give me a good tutorial to follow, so that I can setup GLSL properly.
Regards
Zeeshan
Depending on what you are trying to achieve and what is your current knowledge, you can take different approaches.
If you are trying to learn OpenGL 2.0 while also learning GLSL, I suggest getting the Red book and the Orange book as a set, as they go hand in hand.
If you want a less comprehensive guide that will just get you started, check out the OpenGL bible.
If I misunderstood your question and you already know OpenGL, and want to study more about GLSL in particular, here's a good phong shading example that shows the basics.
Compiling a shader source is really simple,
First you need to allocate a shader slot for your source, just like you allocate a texture, using glCreateShader:
GLuint vtxShader = glCreateShader(GL_VERTEX_SHADER);
GLuint pxlShader = glCreateShader(GL_FRAGMENT_SHADER);
After that you need to load your source code somehow. Since this is really a platform dependent solution, this is up to you.
After obtaining the source, you set it using glShaderSource:
glShaderSource(vtxShader, 1, &vsSource, 0);
glShaderSource(pxlShader, 1, &psSource, 0);
Then you compile your sources with glCompileShader:
glCompileShader(vtxShader);
glCompileShader(pxlShader);
Link the shaders to each other, first allocate a program using glCreateProgram, attach the shaders into the program using glAttachShader, and link them using glLinkProgram:
GLuint shaderId = glCreateProgram();
glAttachShader(shaderId, vtxShader);
glAttachShader(shaderId, pxlShader);
glLinkProgram(shaderId);
Then, just like a texture, you bind it to the current rendering stage using glUseProgram:
glUseProgram(shaderId);
To unbind it, use an id of 0 or another shader ID.
For cleanup:
glDetachShader(shaderId, vtxShader);
glDetachShader(shaderId, pxlShader);
glDeleteShader(vtxShader);
glDeleteShader(pxlShader);
glDeleteProgram(shaderId);
And that's mostly everything to it, you can use the glUniform function family alongside with glGetUniform to set parameters as well.
Related
I'm trying to write a shader for Minecraft bedrock edition, and since I don't have access to the code of the game, just the GLSLes shaders, I was wondering if there was any way for me to access a texture from the fragment shader without having to pass it through the c++ code.
The answer is as stated in the comments above : there's no way. GLSL doesn't work this way.
I have been spending a lot of times tweaking my shaders and I want to quickly reload a shader without recompiling my program. What is the official way to hot reload shaders in OpenGL 4.1?
Here is my current (non-functional) method:
Create a program pipeline, create one separable program per shader (right now it's just one vertex and one fragment) and use it in the pipeline. Load uniforms into each program that needs it (is there a way to mimic the old style of one uniform shared across shaders?)
glGenProgramPipelines(1, &programPipeline);
glBindProgramPipeline(programPipeline); //is this necessary?
auto handle = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(handle, 1, &src, NULL);
glCompileShader(handle);
program[idx] = glCreateProgram();
__glewProgramParameteri(program[idx], GL_PROGRAM_SEPARABLE, GL_TRUE); //xcode auto corrected this for me
glAttachShader(program[idx], handle);
glLinkProgram(program[idx]);
glDetachShader(program[idx], handle);
glUseProgramStages(programPipeline, shaderStage,
program[idx]);
The part I am stuck at is what to do with attributes. It fails with "GL_INVALID_OPERATION" when I try to enable a vertex attrib array when in the normal non-separable programs it would work fine. I have generated and bound a vao and got the attrib location before trying to enable the vertex attrib array. The online resources I've found only mentions uniforms in conjunction with separable programs, but nothing regarding attributes. Can they even be used with separable programs? What would be the alternative?
So I have an opengl program that draws a group on objects. When I draw these objects I want to use my shader program is a vertex shader and a vertex shader exclusively. Basically, I am aiming to adjust the height of the model inside the vertex shader depending on a texture calculation. And that is it. Otherwise I want the object to be drawn as if using naked openGL (no shaders). I do not want to implement a fragment shader.
However I haven't been able to find how to make it so I can have a shader program with only a vertex shader and nothing else. Forgetting the part about adjust my model's height, so far I have:
gl_FrontColor = gl_Color;
gl_Position = modelViewProjectionMain * Position;
It transforms the object to the correct position alright, however when I do this I loose texture coordinates and also lighting information (normals are lost). What am I missing? How do I write a "do-nothing" vertex shader? That is, a vertex shader you could turn off and on when drawing a textured .obj with normals, and there would be no difference?
You can't write a shader with partial implementation. Either you do everything in a shader or completely rely on fixed functionality(deprecated) for a given object.
What you can do is this:
glUseProgram(handle)
// draw objects with shader
glUseProgram(0)
// draw objects with fixed functionality
To expand a little on the entirely correct answer by Abhishek Bansal, what you want to do would be nice but is not actually possible. You're going to have to write your own vertex and fragment shaders.
From your post, by "naked OpenGL" you mean the fixed-function pipeline in OpenGL 1 and 2, which included built-in lighting and texturing. Shaders in OpenGL entirely replace the fixed-function pipeline rather than extending it. And in OpenGL 3+ the old functionality has been removed, so now they're compulsory.
The good news is that vertex/fragment shaders to perform the same function as the original OpenGL lighting and texturing are easy to find and easy to modify for your purpose. The OpenGL Shading Language book by Rost, Licea-Kane, etc has a whole chapter "Emulating OpenGL Fixed Functionality" Or you could get a copy of the 5th edition OpenGL SuperBible book and code (not the 6th edition) which came with a bunch of useful predefined shaders. Or if you prefer online resources to books, there are the NeHe tutorials.
Writing shaders seems a bit daunting at first, but it's easier than you might think, and the extra flexibility is well worth it.
I'm trying to get my transform feedback running. I wanted to specify my buffer layout completely from the shaders using the core 4.4 or the GL_ARB_enhanced_layouts extension using layout (xfb_offset=xx) declarers. I assumed that after declaring these in a vertex shader i can call
GLint iTransformFeedbackVars;
glGetProgramiv(m_uProgramID, GL_TRANSFORM_FEEDBACK_VARYINGS, &iTransformFeedbackVars);
to get the number of potential variables that want to be written to a transform feedback buffer. But my opengl keeps returning 0 for "iTransformFeedbackVars". I tried calling the above command BEFORE and AFTER linking the program.
Am I missing something here or is it even possible to let the shader specify the variables it wants to write to and my code create the buffer(s) after the wishes of the shader?
Im trying to implement modern OpenGL, but the problem is: most tutorials are based on 3.3+, and talk about GLSL 330, I only have GLSL 130. Therefore, many things are apparently different, since my VBO's do not work.
Could you give me general hints or a tutorial that explains how to use GLSL 130 with VBO's? In my case, I have the vbo loaded, but when I use my shader program, only vertices called with glVertex get rendered, it's like the vbo gets ignored (no input). How to solve this?
And can you use VBO's without shaders? I tried to do that, but it crashed...
Yes, VBOs can still be used in GLSL 130, and can still be used even without shaders. The purpose of the VBO is to hold the vertex attributes for drawing. Most up to date tutorials I've seen have you use the layout position specifier for indicating how to address the different attributes in your shader, i.e.
layout(location = 0) in vec3 Position;
This isn't supported in GLSL 130, so you have to have another way of relating the attribute with the VBO. It's pretty simple... you can use glBindAttribLocation or glGetAttribLocation. Calling glGetAttribLocation will give you the identifier you need to use in glVertexAttribPointer to associate the VBO data with the particular attribute. You can call this at any time after the program has been compiled. In addition, you can call glBindAttribLocation to specifically set the identifier that will be associated with a given attribute name if you call it after you've created the program object but before you link the shaders. This is handy because it lets you decide for yourself what the location should be, just as you would be able to with the layout specifier.
Finally, if you want to use a VBO without using a shader at all, then you still have to find a way of associating the data in the VBO with the various inputs that the fixed function pipeline expects. This is done using a now deprecated method called glEnableClientState() and glVertexPointer(), which together let you tell OpenGL what fixed function pipeline attribute you're going to populate, and how it can find the data in the VBO.