Coder Social home page Coder Social logo

gloop's People

Contributors

adbrown85 avatar

Stargazers

 avatar

Watchers

 avatar  avatar

gloop's Issues

Add 3 and 4 component vector implementations

Since OpenGL no longer has math built in, we need to have some vector implementations. There should at least be three and four component versions.

It would be nice to have them match the vectors in GLSL as much as possible. Therefore Vec3 and Vec4 seem to make sense for the names. I'm not sure if they should be capitalized or not though? Also, to make things easy for now we won't worry about doubles. If we think we really need doubles in the future we can make something like Vec3d or Vec4d or even go template-based.

I would like to see the implementations have all the usual vector functions as top-level methods.

  • cross
  • dot
  • length
  • normalize

It would also be nice to have some non-standard ones for convenience.

  • direction
  • distance

Add shader factory utility for creating shaders

Previously we were thinking about having two utilities for creating shaders, ShaderBuilder and ShaderLoader. However, neither of them felt quite right. Believe a combination of them, simply ShaderFactory will be the best. It should be able to create shaders from a file, string, or stream.

ShaderFactory
 + createShaderFromFile(type : GLenum, filename : string) : GLuint
 + createShaderFromString(type : GLenum, str : string) : GLuint
 + createShaderFromStream(type : GLenum, stream : istream) : GLuint

Make core, math, and extensions module

Currently we have several small modules based on what the utilities do, such as math, shader, and texture. However, we think it would be better to put them into two or three larger modules based on whether they wrap something already in OpenGL or whether it's something we've added on top. For example, BufferObject would go in the core module, while BufferObjectLayout would go in the extensions module. We may want to put math into its own module.

Also not sure if the utilities in the core module would go in a core directory, or if they would just go in the root directory.

Matrices made of column vectors

Want to try having matrices made of column vectors to be more like GLSL. Since the vectors override the subscript operator indexing will look more like it. And will easily be able to assign a whole column that way. Not sure if it will be slower or not, but probably not significantly.

Uniform methods for setting value

Currently Uniform just includes information about it, e.g. it's name and type. It would be useful to add methods for setting values. Not only would it be more convenient for the user, since Uniform would take care of sending the right location to glUniform, it could some significant error-checking, e.g. checking the type, size, and whether the current program is the correct one.

Named constructors for matrices from arrays

Currently we have normal constructors for creating matrices from arrays. However, they don't support both row-major and column-major orders, so it'd be better to have named constructors for them. They should be fromArrayInRowMajor and fromArrayInColumnMajor.

Use 'h' for compiled classes, 'hpp' for non-compiled classes

Currently our Makefile makes a distinction between header files. Headers with hpp are assumed to have an accompanying cpp file, and those with h are not. We think this is probably the opposite of the original standards though, since the pp in hpp originally stood for preprocessor. We may want to switch away from using cpp for this as well, since it's ambiguous. We would just use cxx for everything, and rely on names with Test to have main functions.

Tests should not use cassert

Currently a bunch of the tests are using cassert to do tests. Unfortunately if someone configures the project with -DNDEBUG they won't have any effect. Probably will just have to just throw exceptions manually instead. Or I suppose we could try to filter it out with our makefile.

Add BufferObject wrapper

Currently we don't have a wrapper for an OpenGL buffer object. Arguably one isn't necessarily needed, since they are so flexible, and can be bound and rebound to different buffer targets. However, I think if we keep the scope very small, and stick to the existing paradigm, we'll be ok. If nothing else it will be good to have the type safety, especially since glIsBuffer only returns true if the buffer has been bound to a target before.

One way to stick to the existing paradigm would be to make a BufferTarget class. That way buffer targets would bind buffer objects, rather than the other way around. While sort of backwards for the average use case, since most people just use buffer objects for vertex data, and thus think of them as having a fixed target, it would keep things transparent and stateless, so that we don't report things that aren't actually true, and all instances for the same raw OpenGL buffer object would always be equivalent.

BufferObject
 + _generate_() : BufferObject
 + dispose()
 + handle() : GLuint
 + wrap(handle : GLuint) : BufferObject

BufferTarget
 + bindBuffer(BufferObject)
 + data(size : GLsizeiptr, data : const GLvoid*, usage : GLenum)
 + subData(offset : GLintptr, size : GLsizeiptr, data : const GLvoid*)
 + unbind()

BufferTargets
 + array() : BufferTarget
 + elementArray() : BufferTarget
 + texture() : BufferTarget
 + uniform() : BufferTarget

ShaderFactory uses Shader

Currently ShaderFactory just returns a GLuint. It should return an instance of Shader now that we have a wrapper for them.

Variable includes location

Currently Variable includes name, size, and type. It would be useful if it also included its location in the program. Since the index used in glGetActiveAttrib and glGetActiveUniform may not necessarily be its location, we will need to call glGetAttribLocation and glGetUniformLocation when we're making them.

ProgramBuilder uses Program

Currently ProgramBuilder just returns the raw OpenGL handle for the program. However, now that we have a wrapper for programs it should return that instead. Also it should be using the methods in Program to build it.

Add a shader loader

OpenGL considers shaders to be strings (it has no notion of files) so we need to write something to load them from files ourselves.

This will just be a utility with one or two static methods to load a shader from a file given a filename. Although it may be nice to have it optionally take a directory to look in since the filenames can get pretty long sometimes. Ideally it should be able to guess the type of the shader using the file extension. Also for now returning the handle as a GLuint is fine since a designated Shader or ShaderKernel class may be too much for our scope.

Here is a general prototype for the class:

ShaderLoader

  • load(filename : string) : GLuint
  • load(filename : string, type : GLenum) : GLuint

Remove ProgramBuilder

Program is just about as easy to use as ProgramBuilder is, and although a little less automatic, it's more flexible in how the log is handled, so we'll just stick with that for now.

Use stdexcept for exceptions

Should be using the exceptions defined in stdexcept, e.g. invalid_argument and out_of_range, instead of our own Exception class. Most of the math utilities will be affected this. And should remove Exception altogether.

Encapsulate Variable

Currently the fields in Variable are public. At some point we should hide them and provide accessors, or perhaps just make them const, although I'm not sure if that's a good idea considering that prevents users from putting them in standard library containers (because they require a public assignment operator.)

Add VertexArrayObject wrapper

Currently we don't have a wrapper for a vertex array object. It would be nice to have one for type safety. However, this one will probably be very basic, since VAOs were retrofitted in, so most if not all of the functions that modify it are actually global functions.

VertexArrayObject
 + _generate_() : VertexArrayObject
 + bind()
 + dispose()
 + _wrap_(handle : GLuint)

Base class for Attribute and Uniform

Currently Attribute and Uniform are completely separate classes, even though they include the same things. We should break out the fields into a separate abstract base class, probably named Variable, since the OpenGL documentation refers to them as attribute variables and uniform variables.

Variable
 + name() : string
 + size() : GLuint
 + type() : GLenum

Add BufferLayout utility

Since our wrapper for buffer objects will be very general and lightweight, as opposed to having specialized implementations for each use of a buffer, e.g. VertexBufferObject, we may want to have a utility to keep track of what's in a buffer. You would give it a number of regions, where a region is a essentially a name, data type, and count, and then it would compute the stride and offset of those regions for you. If the counts for all of the regions were the same, the layout could be set to interleaved, which would change the offsets.

BufferRegion
 + name() : string
 + type() : GLenum
 + normalized() : bool
 + count() : GLuint

BufferLayout
 + region(BufferRegion)
 + regions() : range<BufferRegion>
 + region(name : string)
 + stride() : GLuint
 + offset(name : string)

Make glycerin namespace lowercase

Think this will make it easier to type, and aligns better with the standard library, boost, the Google coding guidelines, and Java packages at least. Plus think it is nice to make it line up with the directory structure, which I think should definitely be lowercase.

Clean up Program and Shader

There are some things that could be cleaned up in Program. First, its header should include map explicitly. Second, the variable names in activeAttributes and activeUniforms could be named better. Primarily, we should rename buf to name.

Shader wrapper

Currently we're just using GLuint for shaders. It would be good to have a very lightweight Shader class to use instead. Basically it would just hold its handle, and it would just call the appropriate OpenGL functions for everything else. There may be multiple instances of the wrapper pointing to the same OpenGL shader, so it still needs to be manual deleted, probably with a dispose call.

Shader
 + _create_(type : GLenum) : Shader
 + compile()
 + compiled() : bool
 + dispose()
 + handle() : GLuint
 + log() : string
 + source() : string
 + source(string)
 + type() : GLenum
 + _wrap_(handle : GLuint) : Shader

Reenable REPEAT_BRIEF in Doxygen configuration

We currently have the REPEAT_BRIEF option off in the Doxygen configuration. I believe the original reasoning was because it doesn't look good for class documentation. However, it also turns it off for the methods, which in that case they really should be there.

Program wrapper

Currently we're just using GLuint for programs, but it'd be nice to have a type-safe wrapper that also made programs a little easier to work with. Like Shader, it will be very lightweight, just holding its handle. We'll probably need Attribute and Uniform classes to return information about them.

Program
 + _create_() : Program
 + attachShader(shader : Shader)
 + attribLocation(name : string) : GLuint
 + attribLocation(name : string, location : GLuint)
 + attributes() : vector<Attribute>
 + detachShader(shader : Shader)
 + dispose()
 + fragDataLocation(name : string) : GLuint
 + fragDataLocation(name : string, location : GLuint)
 + handle() : GLuint
 + link()
 + linked() : bool
 + log() : string
 + shaders() : vector<Shader>
 + uniforms() : vector<Uniform>
 + use()
 + valid() : bool
 + validate()
 + _wrap_(handle : GLuint) : Program

Add a quaternion implementation

We need a quaternion implementation to support smooth rotations.

The core methods we will need right away are:

  • rotate(Vec3, angle)
  • fromAxisAngle(Vec3, float)
  • toMat3()
  • toMat4()

We may want to make rotate a top-level function though.

In the future it would also be nice to have:

  • fromMat3(Mat3)
  • fromMat4(Mat4)

Add a shader builder

OpenGL is very open-ended when it comes to shaders, which means it takes several steps to make one. For that reason it would be great to have a low-level utility for creating shaders. To keep it in line with traditional design patterns, we would like to call it ShaderBuilder.

To maintain the flexibility of the OpenGL shader API, ShaderBuilder will try to be as low-level as possible yet extremely easy-to-use. For that reason it will basically have two methods. One to add lines, and another to make the shader. Here is a simple UML stub for the class:

ShaderBuilder

  • addLine(line : string)
  • toShader(type : GLenum) : GLuint

To make it even simpler, there will be no clear method. When toShader is called it will just make the shader and then clear all its state automatically.

OpenGL is of course meant to be used with C so the user is required to check errors explicitly. Again, to make things easy ShaderBuilder will not require that. When toShader is called it will check that the shader compiled successfully. If it did not it will throw an exception with the log message.


Some issues that are worth considering:

  • Should we append newline characters to the lines that are added?
  • Should we allow empty lines?

Add 3 and 4 width square matrix implementations

Since OpenGL no longer has matrix math built-in, we need to make some matrix implementations. For 3D graphics I think three and four width square matrices are enough.

Like our vectors, it would be nice to have them mirror the GLSL implementations as much as possible. Therefore the names should probably be Mat3 and Mat4. (We'll go with capitals for now to be consistent with other types in the library...) To make things easy for now we'll just stick with floats. If we need doubles later we can tack on a d at the end of the name, similar to what GLSL does, or even go template based.

Besides all the necessary operators, they should have a few extra top-level functions that users will expect.

  • inverse
  • transpose

Also we will want some toArray methods so we can easily send the values to OpenGL shaders, or just for users that want or need to work with arrays. We will assume the single-index forms are in column-major order though. We won't support dumping down to a pointer because there's no way to know the dimensions of that.

  • toArray(float[3][3])
  • toArray(float[4][4])
  • toArray(float[9])
  • toArray(float[16])

Add texture utilities

We'll need to have some type of texture support. We already have some leftover from past projects. Will just need to adapt those. Probably just 2D and 3D versions for right now.

Rename Program uniforms to activeUniforms

Currently our wrapper around glGetActiveUniform in Program is just called uniforms. Calling it activeUniforms instead would make it closer to pure OpenGL, and would help emphasize that some uniforms may be compiled out of a program.

Add Viewport utility

Having a utility that held the location and size of a viewport would be useful to the projections.

Viewport
 + Viewport(x : int, y : int, width : int, height : int)
 + x() : int
 + y() : int
 + width() : int
 + height() : int

We'll keep the x, y, width, and height attributes private but not final so a viewport is essentially immutable but can still be put into an STL container.

Rename Program attributes to activeAttributes

Currently our wrapper around glGetActiveAttrib in Program is just called attributes. Calling it activeAttributes instead would make it closer to pure OpenGL, and would help emphasize that some attributes may be compiled out of a program.

Fix Mat4Test failing

Currently some test cases in Mat4Test are failing. They are testCreateSignChart and testInverse.

ProgramBuilder utility for creating shader programs

We should have a utility to help us create shader programs.

Since shader programs can be made up of an arbitrary number of shaders, and can have arbitrary attribute bindings, for this one I think it really does make sense to use the builder pattern here. Otherwise we'd have to take some type of collection for the shaders, and then probably a map for the attribute bindings, which could quickly get pretty messy. Plus, although I haven't looked into it yet, it would probably extend better to the new OpenGL 4 stuff that's been added recently.

Here's a mockup of what should probably be in there:

ProgramBuilder
 + addShader(shader : GLuint) : void
 + bindAttribute(index : GLuint, name : string) : void
 + reset() : void
 + toProgram() : GLuint

UniformLocation utility

Currently we haven't exposed any abstraction for uniforms. While we could make an all-encompassing Uniform class, limiting the scope to just the location would be more in line with the paradigm OpenGL is using. To elaborate, we cannot change the value of specific uniforms in whatever program we wish whenever we want, we can only change the value of a uniform at a specific location in the current program. Naming the utility UniformLocation and keeping it small in scope will help enforce that idea.

Remove Mat3

Probably isn't necessary to keep this around. Really we should be doing everything with four-by-four matrices and four-component vectors, with the exception where cross products are needed.

Add operator== to Shader

Currently to see if a Shader instance is the same as another, we have to check their handles. Should be able to just use the equality operator.

Program attributes and uniforms should return maps

Currently attributes and uniforms in Program return a vector of Attribute and Uniform structures, respectively. Often a user will want to query them by name, however, so it would be better if they returned a map instead. The user might want to know the type/size, or maybe whether the variable got compiled out.

Add BufferObject::disposed

Currently we have a dispose method to delete the corresponding OpenGL buffer object, but we don't have a way to check if that ever actually happened. We should add a method to query that state from OpenGL. Naming it disposed would make sense, but I'm not sure that captures what's intended, since the application could call dispose on a handle and disposed might not return true for awhile. In that sense deleted would be better, except then we get lumped in with the C++ delete keyword. Probably best to just call it disposed.

Add dependency on boost::filesystem

Currently we don't have a very good way to deal with files and directories. Having path from boost would help a lot, and it's about as standard as we can get. We want it in ShaderFactory, possibly for a directory that it looks for files in by default, and also for getting some type of include functionality back in. I anticipate this will come up in other spots too.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.