Are all returned values of glGetInternalformat dependant on both the target and format arguments? - opengl

In the OpenGL 4.6 specification under section 22.3, a command named glGetInternalformat is described which can be used to gather implementation dependent information about internal formats.
The command have the following signatures listed in the specification:
void GetInternalformativ( enum target, enum internalformat, enum pname, sizei count, int *params );
void GetInternalformati64v( enum target, enum internalformat, enum pname, sizei count, int64 *params );
The valid values for pname according to the specification are:
// Supported operations
GL_CLEAR_BUFFER
GL_CLEAR_TEXTURE
GL_COMPUTE_TEXTURE
GL_FILTER
GL_FRAGMENT_TEXTURE
GL_FRAMEBUFFER_BLEND
GL_FRAMEBUFFER_RENDERABLE
GL_FRAMEBUFFER_RENDERABLE_LAYERED
GL_GEOMETRY_TEXTURE
GL_MANUAL_GENERATE_MIPMAP
GL_READ_PIXELS
GL_SHADER_IMAGE_ATOMIC
GL_SHADER_IMAGE_LOAD
GL_SHADER_IMAGE_STORE
GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST
GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE
GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST
GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE
GL_SRGB_READ
GL_SRGB_WRITE
GL_TESS_CONTROL_TEXTURE
GL_TESS_EVALUATION_TEXTURE
GL_TEXTURE_GATHER
GL_TEXTURE_GATHER_SHADOW
GL_TEXTURE_SHADOW
GL_TEXTURE_VIEW
GL_VERTEX_TEXTURE
// Other
GL_COLOR_COMPONENTS
GL_COLOR_ENCODING
GL_COLOR_RENDERABLE
GL_DEPTH_COMPONENTS
GL_DEPTH_RENDERABLE
GL_GET_TEXTURE_IMAGE_FORMAT
GL_GET_TEXTURE_IMAGE_TYPE
GL_IMAGE_COMPATIBILITY_CLASS
GL_IMAGE_FORMAT_COMPATIBILITY_TYPE
GL_IMAGE_PIXEL_FORMAT
GL_IMAGE_PIXEL_TYPE
GL_IMAGE_TEXEL_SIZE
GL_INTERNALFORMAT_PREFERRED
GL_INTERNALFORMAT_RED_SIZE
GL_INTERNALFORMAT_GREEN_SIZE
GL_INTERNALFORMAT_BLUE_SIZE
GL_INTERNALFORMAT_ALPHA_SIZE
GL_INTERNALFORMAT_DEPTH_SIZE
GL_INTERNALFORMAT_STENCIL_SIZE
GL_INTERNALFORMAT_SHARED_SIZE
GL_INTERNALFORMAT_RED_TYPE
GL_INTERNALFORMAT_GREEN_TYPE
GL_INTERNALFORMAT_BLUE_TYPE
GL_INTERNALFORMAT_ALPHA_TYPE
GL_INTERNALFORMAT_DEPTH_TYPE
GL_INTERNALFORMAT_STENCIL_TYPE
GL_INTERNALFORMAT_SUPPORTED
GL_MAX_COMBINED_DIMENSIONS
GL_MAX_DEPTH
GL_MAX_HEIGHT
GL_MAX_LAYERS
GL_MAX_WIDTH
GL_MIPMAP
GL_NUM_SAMPLE_COUNTS
GL_READ_PIXELS_FORMAT
GL_READ_PIXELS_TYPE
GL_SAMPLES
GL_STENCIL_COMPONENTS
GL_STENCIL_RENDERABLE
GL_TEXTURE_COMPRESSED
GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT
GL_TEXTURE_COMPRESSED_BLOCK_SIZE
GL_TEXTURE_COMPRESSED_BLOCK_WIDTH
GL_TEXTURE_IMAGE_FORMAT
GL_TEXTURE_IMAGE_TYPE
GL_VIEW_COMPATIBILITY_CLASS
My question is if for all those pname values that can be queried, do any of them not require both the target and internalformat parameters? Are there some pnames that will result in the same returned value regardless of which target is used and are there any pnames that return the same value regardless of internalformat? The specification is not clear on this.
The reason I am asking this is because some pnames seems to be information about the internalformat and has nothing to do with the target. I assume that the people behind opengl did not want to create a seperate set of commands for pnames that do not require both target and internalformat and instead used a single set of commands for all cases.
If a list of the pname values for which the target do not matter and a list of pname values for which the internalformat do not matter (if there are any) could be created and these lists are guaranteed to be the same on all platforms, then one could simply wrap the command and hard code a constant value for those arguments and remove the need for those parameters. This would simplify the gathering of information on internalformats and targets (if there are any target specific information).

The standard makes it pretty clear which things care about the target and which do not. It describes how each pname query works and it uses specific keywords in those descriptions. Specifically, it says this up-front:
In the following descriptions, the term resource is used to generically refer to an object of the appropriate type that has been created with internalformat and target.
So, if the description for a query does not use the words "target" or "resource", then it doesn't care about them.

Related

c++ best way to realise global switches/flags to control program behaviour without tying the classes to a common point

Let me elaborate on the title:
I want to implement a system that would allow me to enable/disable/modify the general behavior of my program. Here are some examples:
I could switch off and on logging
I could change if my graphing program should use floating or pixel coordinates
I could change if my calculations should be based upon some method or some other method
I could enable/disable certain aspects like maybe a extension api
I could enable/disable some basic integrated profiler (if I had one)
These are some made-up examples.
Now I want to know what the most common solution for this sort of thing is.
I could imagine this working with some sort of singelton class that gets instanced globally or in some other globally available object. Another thing that would be possible would be just constexpr or other variables floating around in a namespace, again globally.
However doing something like that, globally, feels like bad practise.
second part of the question
This might sound like I cant decide what I want, but I want a way to modify all these switches/flags or whatever they are actually called in a single location, without tying any of my classes to it. I don't know if this is possible however.
Why don't I want to do that? Well I like to make my classes somewhat reusable and I don't like tying classes together, unless its required by the DRY principle and or inheritance. I basically couldn't get rid of the flags without modifying the possible hundreds of classes that used them.
What I have tried in the past
Having it all as compiler defines. This worked reasonably well, however I didnt like that I couldnt make it so if the flag file was gone there were some sort of default settings that would make the classes themselves still operational and changeable (through these default values)
Having it as a class and instancing it globally (system class). Worked ok, however I didnt like instancing anything globally. Also same problem as above
Instancing the system class locally and passing it to the classes on construction. This was kinda cool, since I could make multiple instruction sets. However at the same time that kinda ruined the point since it would lead to things that needed to have one flag set the same to have them set differently and therefore failing to properly work together. Also passing it on every construction was a pain.
A static class. This one worked ok for the longest time, however there is still the problem when there are missing dependencies.
Summary
Basically I am looking for a way to have a single "place" where I can mess with some values (bools, floats etc.) and that will change the behaviour of all classes using them for whatever, where said values either overwrite default values or get replaced by default values if said "place" isnt defined.
If a Singleton class does not work for you , maybe using a DI container may fit in your third approach? It may help with the construction and make the code more testable.
There are some DI frameworks for c++, like https://github.com/google/fruit/wiki or https://github.com/boost-experimental/di which you can use.
If you decide to use switch/flags, pay attention for "cyclometric complexity".
If you do not change the skeleton of your algorithm but only his behaviour according to the objets in parameter, have a look at "template design pattern". This method allow you to define a generic algorithm and specify particular step for a particular situation.
Here's an approach I found useful; I don't know if it's what you're looking for, but maybe it will give you some ideas.
First, I created a BehaviorFlags.h file that declares the following function:
// Returns true iff the given feature/behavior flag was specified for us to use
bool IsBehaviorFlagEnabled(const char * flagName);
The idea being that any code in any of your classes could call this function to find out if a particular behavior should be enabled or not. For example, you might put this code at the top of your ExtensionsAPI.cpp file:
#include "BehaviorFlags.h"
static const enableExtensionAPI = IsBehaviorFlagEnabled("enable_extensions_api");
[...]
void DoTheExtensionsAPIStuff()
{
if (enableExtensionsAPI == false) return;
[... otherwise do the extensions API stuff ...]
}
Note that the IsBehaviorFlagEnabled() call is only executed once at program startup, for best run-time efficiency; but you also have the option of calling IsBehaviorFlagEnabled() on every call to DoTheExtensionsAPIStuff(), if run-time efficiency is less important that being able to change your program's behavior without having to restart your program.
As far as how the IsBehaviorFlagEnabled() function itself is implemented, it looks something like this (simplified version for demonstration purposes):
bool IsBehaviorFlagEnabled(const char * fileName)
{
// Note: a real implementation would find the user's home directory
// using the proper API and not just rely on ~ to expand to the home-dir path
std::string filePath = "~/MyProgram_Settings/";
filePath += fileName;
FILE * fpIn = fopen(filePath.c_str(), "r"); // i.e. does the file exist?
bool ret = (fpIn != NULL);
fclose(fpIn);
return ret;
}
The idea being that if you want to change your program's behavior, you can do so by creating a file (or folder) in the ~/MyProgram_Settings directory with the appropriate name. E.g. if you want to enable your Extensions API, you could just do a
touch ~/MyProgram_Settings/enable_extensions_api
... and then re-start your program, and now IsBehaviorFlagEnabled("enable_extensions_api") returns true and so your Extensions API is enabled.
The benefits I see of doing it this way (as opposed to parsing a .ini file at startup or something like that) are:
There's no need to modify any "central header file" or "registry file" every time you add a new behavior-flag.
You don't have to put a ParseINIFile() function at the top of main() in order for your flags-functionality to work correctly.
You don't have to use a text editor or memorize a .ini syntax to change the program's behavior
In a pinch (e.g. no shell access) you can create/remove settings simply using the "New Folder" and "Delete" functionality of the desktop's window manager.
The settings are persistent across runs of the program (i.e. no need to specify the same command line arguments every time)
The settings are persistent across reboots of the computer
The flags can be easily modified by a script (via e.g. touch ~/MyProgram_Settings/blah or rm -f ~/MyProgram_Settings/blah) -- much easier than getting a shell script to correctly modify a .ini file
If you have code in multiple different .cpp files that needs to be controlled by the same flag-file, you can just call IsBehaviorFlagEnabled("that_file") from each of them; no need to have every call site refer to the same global boolean variable if you don't want them to.
Extra credit: If you're using a bug-tracker and therefore have bug/feature ticket numbers assigned to various issues, you can creep the elegance a little bit further by also adding a class like this one:
/** This class encapsulates a feature that can be selectively disabled/enabled by putting an
* "enable_behavior_xxxx" or "disable_behavior_xxxx" file into the ~/MyProgram_Settings folder.
*/
class ConditionalBehavior
{
public:
/** Constructor.
* #param bugNumber Bug-Tracker ID number associated with this bug/feature.
* #param defaultState If true, this beheavior will be enabled by default (i.e. if no corresponding
* file exists in ~/MyProgram_Settings). If false, it will be disabled by default.
* #param switchAtVersion If specified, this feature's default-enabled state will be inverted if
* GetMyProgramVersion() returns any version number greater than this.
*/
ConditionalBehavior(int bugNumber, bool defaultState, int switchAtVersion = -1)
{
if ((switchAtVersion >= 0)&&(GetMyProgramVersion() >= switchAtVersion)) _enabled = !_enabled;
std::string fn = defaultState ? "disable" : "enable";
fn += "_behavior_";
fn += to_string(bugNumber);
if ((IsBehaviorFlagEnabled(fn))
||(IsBehaviorFlagEnabled("enable_everything")))
{
_enabled = !_enabled;
printf("Note: %s Behavior #%i\n", _enabled?"Enabling":"Disabling", bugNumber);
}
}
/** Returns true iff this feature should be enabled. */
bool IsEnabled() const {return _enabled;}
private:
bool _enabled;
};
Then, in your ExtensionsAPI.cpp file, you might have something like this:
// Extensions API feature is tracker #4321; disabled by default for now
// but you can try it out via "touch ~/MyProgram_Settings/enable_feature_4321"
static const ConditionalBehavior _feature4321(4321, false);
// Also tracker #4222 is now enabled-by-default, but you can disable
// it manually via "touch ~/MyProgram_Settings/disable_feature_4222"
static const ConditionalBehavior _feature4222(4222, true);
[...]
void DoTheExtensionsAPIStuff()
{
if (_feature4321.IsEnabled() == false) return;
[... otherwise do the extensions API stuff ...]
}
... or if you know that you are planning to make your Extensions API enabled-by-default starting with version 4500 of your program, you can set it so that Extensions API will be enabled-by-default only if GetMyProgramVersion() returns 4500 or greater:
static ConditionalBehavior _feature4321(4321, false, 4500);
[...]
... also, if you wanted to get more elaborate, the API could be extended so that IsBehaviorFlagEnabled() can optionally return a string to the caller containing the contents of the file it found (if any), so that you could do shell commands like:
echo "opengl" > ~/MyProgram_Settings/graphics_renderer
... to tell your program to use OpenGL for its 3D graphics, or etc:
// In Renderer.cpp
std::string rendererType;
if (IsDebugFlagEnabled("graphics_renderer", &rendererType))
{
printf("The user wants me to use [%s] for rendering 3D graphics!\n", rendererType.c_str());
}
else printf("The user didn't specify what renderer to use.\n");

v8::ObjectTemplate::SetAccessor and v8::Template::Set - Difference

I'm confused by the difference between V8 ObjectTemplate's Set and SetAccessor methods. My question has a simple context and 4 concrete sub-questions.
Context
Let's say I have code snippet that wants to provide a global object global to the targeting JS context. global has a property x, whose value takes int value. global also has a property log, which is a function. All the snippets are taken from V8's source, process.cc and Embedder's Guide to be precise.
HandleScope handle_scope(GetIsolate());
// Create a template for the global object where we set the
// built-in global functions.
Local<ObjectTemplate> global = ObjectTemplate::New(GetIsolate());
global->Set(String::NewFromUtf8(GetIsolate(), "log",
NewStringType::kNormal).ToLocalChecked(),
FunctionTemplate::New(GetIsolate(), LogCallback));
So this code snippet provides function log to the global. Then from the Embedder's Guide to accessors, it says
An accessor is a C++ callback that calculates and returns a value when an object property is accessed by a JavaScript script. Accessors are configured through an object template, using the SetAccessor method.
The code snippet follows:
void XGetter(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
info.GetReturnValue().Set(x);
}
void XSetter(Local<String> property, Local<Value> value,
const PropertyCallbackInfo<Value>& info) {
x = value->Int32Value();
}
// YGetter/YSetter are so similar they are omitted for brevity
Local<ObjectTemplate> global_templ = ObjectTemplate::New(isolate);
global_templ->SetAccessor(String::NewFromUtf8(isolate, "x"), XGetter, XSetter);
global_templ->SetAccessor(String::NewFromUtf8(isolate, "y"), YGetter, YSetter);
Persistent<Context> context = Context::New(isolate, NULL, global_templ);
As I understand this code snippet, it's providing some integer value x to the global as the description goes.
Now,from the source of V8, I see ObjectTemplate doesn't have a Set method, instead, it's inherited from parent class Template. From Template's source code, it says:
/**
* Adds a property to each instance created by this template.
*
* The property must be defined either as a primitive value, or a template.
*/
void Set(Local<Name> name, Local<Data> value,
propertyAttribute attributes = None);
Questions
Template's Set method says it can set a primitive value to the instance of the template, then can I use Set to set x in the second code snippet instead of using SetAccessor?
If the answer to question 1 is true, then what's the difference for setting x between using SetMethod and Set? Is the difference being that any modification in JS to the property set by Set will not be reflected in C++?
If the answer to question 1 is false, then why can't I use Set on X?
From the description of accessors, it says it computes and return value. So does it mean we don't use SetAccessor to return functions? I'm confused because I mainly write JS and Haskell. Both languages spoils me to take functions as values.
Now I know it should be easy to verify all my assumptions by actually building the samples, but I have difficulties compiling the V8 source, hence I'm asking for any help.
Thank you in advanced for any effort!
1. Yes.
2. Set is the C++ equivalent (modulo property attributes) of:
Object.defineProperty(global, "x", {value: 3})
SetAccessor is the C++ equivalent of:
Object.defineProperty(global, "x", {get: function XGetter() { return ...; },
set: function XSetter(val) { ... }});
As you suggest, a consequence is that in case of Set, the C++ side has no way of knowing whether the value was changed from the JavaScript side.
3. n/a
4. The getter can return any value you want; in particular the value can be a function.

FindResource giving error 1813 when loading png

I'm attempting to follow this tutorial on the MSDN to load an image file from a resource. I've a feeling some of the code provided is guff, but I can't figure out how to make it work. The call to FindResource() keeps failing with error code 1813.
I've added a .rc resource file to my C++ project (I'm using Visual Studio 2013 as my IDE), and added a png file with the ID IDB_PNG1:
The tutorial defines the resource as IDR_SAMPLE_IMAGE IMAGE "turtle.jpg", and then calls FindResource() as
FindResource(
NULL, // This component.
L"SampleImage", // Resource name.
L"Image"); // Resource type.
I've a feeling that L"SampleImage" is supposed to be L"IDR_SAMPLE_IMAGE" and L"Image" is supposed to be L"IMAGE", since the provided values don't seem to exist anywhere, but my equivalent call doesn't work:
FindResource(
NULL, // This component
"IDB_PNG1", // Resource name
"PNG", // Resource type
);
What am I doing wrong?
I don't know if it's related, but whenever I use L"string" in my code, I get an error (Argument of type "const wchar_t *" is incompatible with parameter of type "LPCSTR"), so I've been omitting the L which seems to have worked for every other example I've followed, so I don't think that's the issue here.
The sample is a little muddled with that "SampleImage" name. The confusing part is that Win32 resources may be identified with either strings or (16-bit) integers. The sample leads you to use strings (e.g. L"SampleImage"), but the Visual Studio IDE (and, frankly, most code I've come across) prefers integers. To allow both kinds, the Win32 resource functions take parameters of type LPCWSTR and callers are supposed to use a macro, MAKEINTRESOURCE, to convert an integer ID into a "pseudo string". The same applies for resource types. There are some built-in types (ICON, CURSOR, BITMAP, et al), but you can always define your own types using strings.
If you look around in your code, you should be able to find a header file (Resource.h, probably) with the definition for IDB_PNG1. It's most likely a small integer, so you need to use the MAKEINTRESOURCE macro. PNG was probably not defined anywhere, and it's not one of the built-in resource types, so the resource compiler treated it as a string and so should you.
e.g.
FindResource(
NULL, // This component
MAKEINTRESOURCE(IDB_PNG1), // Resource name
L"PNG", // Resource type
);
Try that and let us know if it works.

ADO Command saying that I am inserting NULL, when I'm not

I'm using ADO to communicate with my Sybase server..
This is how I'm executing a simple command:
_ConnectionPtr m_ConnPtr;
//... Instantiate connection
_CommandPtr m_CommPtr;
m_CommPtr->CreateInstance(__uuidof(Command))
m_CommPtr->ActiveConnection = m_ConnPtr;
Variant m_variant;
m_variant.SetString("My Param Value");
_ParameterPtr ParamPtr;
ParamPtr = m_CommPtr->CreateParameter("#StrParam", (DataTypeEnum) m_variant.vt, adParamInput, NULL, m_variant);
m_CommPtr->Parameters->Append(PrmPtr);
m_CommPtr->CommandText = "EXECUTE my_stored_procedure #StrParam";
m_CommPtr->Execute(NULL, NULL, adOptionUnspecified);
#StrParam is supposed to be a VarChar type..
Running this gives me an error:
Attempt to insert NULL value into column 'StrParam'. table 'MYTABLE';
column does not allow nulls. Update fails.
I'm not sure why I'm getting this error, since I am specifiying its value ("My Param Value")..
Does anyone know what I'm doing wrong?
(I didn't include the Stored procedure,, because I'm sure there's nothing wrong with the procedure itself.. Other application using the same procedure works fine. So there must be something wrong with how I'm using the parametized command)
I have no clue what your Variant class even is. But the traditional variant type (vt) and the ADO data type are not synonymous. Second, you're not setting up the call nor parameters correctly for a typical stored-proc invoke.
Below is how you would do this using a standard stored proc call and variant_t from the comutil library:
_CommandPtr m_CommPtr(__uuidof(Command));
m_CommPtr->ActiveConnection = m_ConnPtr;
m_CommPtr->CommandType = adoCmdStoredProc;
m_CommPtr->CommandText = L"my_stored_procedure";
// setup parameter
variant_t vParam = L"My Param Value";
_ParameterPtr ParamPtr = m_CommPtr->CreateParameter(L"#StrParam", adBSTR, adParamInput, 0, vParam);
m_CommPtr->Parameters->Append(ParamPtr);
m_CommPtr->Execute(NULL, NULL, adOptionUnspecified);
Note that the ParamPtr is generally optional and you can straight-away append the parameter to the command's Parameters collection if you don't need it for anything else, like this:
m_CommPtr->Parameters->Append(m_CommPtr->CreateParameter(
L"#StrParam", adBSTR, adParamInput, 0, vParam));
The method you're using is common for parameters that are both input and output, as you retain the parameter object reference to extract the output side of the parameter. I see no evidence of that in your call, which is the only reason I mention it here.
Also note that unless the command returns rows for a result set you should also invoke with adExecuteNoRecords for the execution third option (which is typical for many fire-and-forget stored procedure executions)
Finally, the names of the parameters are not important unless you use the NamedParameters property of the command object. This is commonly done when you have additional parameters with default values that you would like to retain, setting only specific parameters as part of your append list.
Best of luck.

How to create a CgFx like effect system?

Seriouse graphics engine like CryEngine3, Unreal Engine 3 have their customized shader language and effect system. While trying to find some effect system for my small graphics framework, it looks like nvidia CgFx is the only choice (seems Khronos had a project called glFx, but the project page is 404 now).
I have several reasons to make a effect system of my own:
I need more control about how and when to pass the shader parameters.
In order to reuse shader snippets, I want to create some c++ macro like mechanism. It's also useful to use macro to do some conditional compilation, and that the way CryEngine used to produces various effects.
Looks like GLSL don't have such effect system
so I am wondering how to create a effect system? Do I need to write grammar parser from scratch or there's already some code/tools able to do this thing?
PS: I am using OpenGL with both GLSL and CG.
Back in the day when I was using HLSL, I developped a little shader system which allowed me to specify all my parameters through data, so that I could just edit a sort of XML file containing the list of parameters and the shader codes, and after saving, the engine would automatically reload it, rebind all parameters, etc.
It's nothing compared to what's found in the UDK, but pretty convenient, and I guess you're trying to implement something like that ?
I it is, then here are a few stuff to do. First, you need to create a class to abstract shader parameter handling (binding, setting, etc.) Something along these lines :
class IShaderParameter
{
protected:
IShaderParameter(const std::string & name)
: m_Uniform(-1)
, m_Name(name)
{}
GLuint m_Uniform;
std::string m_Name;
public:
virtual void Set(GLuint program) = 0;
};
Then, for static parameters, you can simply create an overload like this :
template < typename Type >
class StaticParameter
: public IShaderParameter
{
public:
StaticParameter(const std::string & name, const Type & value)
: IShaderParameter(name)
, m_Value(value)
{}
virtual void Set(GLuint program)
{
if (m_Uniform == -1)
m_Uniform = glGetUniformLocation(program, m_Name.c_str());
this->SetUniform(m_Value);
}
protected:
Type m_Value;
void SetUniform(float value) { glUniform1f(m_Uniform, value); }
// write all SetUniform specializations that you need here
// ...
};
And along the same idea, you can create a "dynamic shader parameter" type. For example, if you want to be able to bind a light's parameter to your shader, create a specialized parameter's type. In its constructor, pass the light's id so that it will know how to retrieve the light in the Set method. With a little work, you can have a whole bunch of parameters that you can then automatically bind to an entity of your engine (material parameters, light parameters, etc.)
The last thing to do is create a little custom file format (I used xml) to define your various parameters, and a loader. For example, in my case, it looked like this :
<shader>
<param type="vec3" name="lightPos">light_0_position</param>
<param type="vec4" name="diffuse">material_10_diffuse</param>
<vertexShader>
... a CDATA containing your shader code
</vertexShader>
</shader>
In my engine, "light_0_position" would mean a light parameter, 0 is the light's ID, and position is the parameter to get. Binding between the parameter and the actual value was done during loading so there was not much overhead.
Anyway, I don't if that answer your question, and don't take these sample codes too seriously (HLSL and OpenGL shaders work quite differently, and I'm no OpenGL expert ^^) but hopefully it'll give you a few leads :)
Could you elaborate on this? By working with OpenGL directly you have a full control over the parameters being passed to the GPU. What exactly are you missing?
(and 3.) GLSL does support re-using the code. You can have a library of shaders providing different functions. In order to use any function you just need to pre-declare it in the client shader (vec4 get_diffuse();) and attach the shader object implementing the function to the shader program before linking.