Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6364437
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T00:09:49+00:00 2026-05-25T00:09:49+00:00

Since I have started learning OpenGL, I thought I would as well write a

  • 0

Since I have started learning OpenGL, I thought I would as well write a small C++ framework (for myself) to avoid the nausea that the excessive use of C-ish code is apparently causing. :) Since I am intending to stick with Qt, the framework uses some Qt classes.

The first thing I really needed was an easy way to use shaders and programs. Here’s my idea of the shader class.

class Shader
{
public:
    //create a shader with no source code 
    explicit Shader(GLenum shaderType);
    //create a shader with source code and compile it
    Shader(GLenum shaderType, const QString& sourceCode);
    //create a shader from source file and compile it
    Shader(GLenum shaderType, QFile& sourceFile);
    ~Shader();

    //change the source code and recompile
    void Source(QFile& sourceFile);
    void Source(const QString& sourceCode);

    GLuint get() const; //get the handle

private:
    //common part for creation in different constructors
    void createShader(GLenum shaderType); 
    //compile
    void compile();

private:
    GLuint handle;
};

It must be pretty obvious what the different functions are doing. Each is calling the relevant OpenGL routines, checks for errors and throws exceptions in case of any failure. The constructor calls glCreateShader. Now the tricky part. The destructor needs to call glDeleteShader(handle); but in this case I have a dilemma:

Option 1: Disable assignment and copying. This has the upside of avoiding reference counting and the downside of being forced to use shared_pointers to put these in vectors and passing around in general.

Option 2: Enable reference counting. This has the obvious upside of enabling copying, and therefore storing in containers(which I will need to later pass a range of shaders to a program). The downside is the following:

Shader s1(GL_VERTEX_SHADER, QFile("MyVertexShader.vp"));
Shader s2(s1);
s2.Source(QFile("MyOtherVertexShader.vp"));

As you see, I changed the source of s1 via s2, because they share the same internal shader handle. To be honest, I don’t see a big problem here. I wrote the class, so I know its copy-semantics are like this and I’m OK with it. The problem is I am not sure this kind of design is ever acceptable. All this could be achieved with Option1 + shared pointers, with the only difference that I don’t want to have a shared pointer every time I create a shader (not for performance reasons – just for syntactic convenience).

Q1: Please comment on the options and optionally the whole idea.1
Q2: If I were to choose option 2, do I have to implement it myself or there’s a ready class in boost or Qt which I could derive from or have a member of and I would get a free reference counting?
Q3: Do you agree that making Shader an abstract class and having three derived classes VertexShader, FragmentShader, and GeometryShader would be overkill?

1 If you should refer me to an existing C++ OpenGL framework, that’s very good(since I haven’t actually found one) but that should really be a side note than an answer to my questions. Also note that I have seen a QGLShader class somewhere in the docs, but it is apparently not present in my version of Qt and I have my reasons to avoid upgrading right now.

UPDATE

Thanks for the answers. I eventually decided to make my shader class immutable by removing the source functions. The shader gets compiled at creation and has no non-const member-functions. Thus a simple reference counting solves all my problems at once.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T00:09:49+00:00Added an answer on May 25, 2026 at 12:09 am

    I say use option 1: it can do everything option 2 can (via smart pointers), whereas option 2 makes you pay the indirection cost even when you don’t need it. On top of that, it’s arguably easier to write.

    Similarly I’ve once considered using handle-body/PIMPL when wrapping over a C API, to allow returning objects from functions (the C handle type wasn’t guaranteed copyable, so the indirection was necessary for that). I decided against it since std::unique_ptr<T> does the non-movable -> movable transformation (much as shared_ptr<T> makes T copyable). Since then I design my classes to have the ‘tightest’ move/copy semantics.

    You do have a point when it comes to syntactical noise however! Things like Boost.Phoenix and lambdas tend to help. If/when they are not an option, I’d say writing a separate shared_shader or whatever wrapper (wrapper wrapper?) makes sense, at least for library-level code (which I believe is the case here). I don’t know of any utility to help with the tediousness of writing the forwarding functions.

    I also don’t know much when it comes to shaders so I’m not sure I can answer your last question. I think making a class hierarchy would make sense if the number of different shaders were liable to change often. I don’t think that’s the case; I also think even if that were the case since the implementation at your level is wrapping a preexisting API it’s not too much of a hassle to revisit the code to forward to that API if/when a new shader is added.


    Since you’re asking for an example of Phoenix niceness.

    What I want to do assuming I don’t have to dereference:

    std::transform(begin, end, functor);
    

    Instead:

    std::for_each(begin, end, *arg1 = ref(functor)(*arg1));
    

    It’s possible to still use std::transform (desirable for clarity) using some Phoenix facilities (construct IIRC) but that would cost an allocation.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Since I have started learning about rendering to a texture I grew to understand
I've just started learning how to use the Entity Framework to write a very
Since I started learning Objective-C and Cocoa, I've been wondering why they have chosen
Since I have started using this site, I keep hearing about the Boost library.
I have recently started creating an iPhone application using Appcelerator's Titanium. Since the application
Since I've started to use jQuery, I have been doing a lot more JavaScript
Ever since I started programming this has been something I have been curious about.
I have been dabbling in programming/scripting languages since I was a kid. I started
I have started learning Ruby for the past 2,3 weeks and I have come
I have recently started learning C++ and coming from a Ruby environment I have

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.