I am using C++ and OpenGL. I'm trying to do some mock design of a model loader and renderer.
Here is where I'm getting stuck:
I have been drawing to the screen with my renderer class and window class, no problems there.
I'm using a generic model class that until now was hard coded to take vertices[108] and colors[108] and draw a cube. This works and I could instance hundreds of cubes just fine. However, I was always creating the model(s) by using vertices[108] and colors[108].
Now I want to ditch the [108] and just pass vertices and colors of any sizes into the model constructor.
Right now it looks like in pseudo code:
//this is in main.cpp
GLfloat vertices[108] = {
//vertices here
};
GLfloat colors[108] = {
//colors
};
mynamespace::Model::cube(vertices,colors);
That is how I a have been using this and within the model class:
`//this is in model class declaration
GLfloat vertices_[108];
GLfloat colors_[108];
//then in the constructor definition
Model::Model(vertices,colors) {
//loop through, i<108, and assign vertices,colors to vertices_,colors_
}
`
This has worked fine for learning purposes. I now would like to start creating various size vertices[] and sending them along to the Model constructor. (The number of vertices and colors will match - will check that). But I am having a hard time removing that hard coded index, e.g. vertices[108], and just sending along vertices[unknown until it arrives].
I thought, worst case, I could send a vertices[] through and then in the constructor defn, receive the vertices, check the sizeof() and divide by 4 and assign values by loop if nothing else would work. However, when I send any size vertices[] through and print out the sizeof() to check it, I always get 4 bytes...and nothing draws of course.
To be clear, I'm not getting errors in my code and I don't have a particular code I want to debug so I'm not pasting an existing code sample to solve anything. This is meant to be here is what I'm trying to do, what are some recommendations from experienced folks.
What is a good practice for doing this type of thing?
After this, I want to start loading mesh from files but first I want to understand how I am supposed to pass along various amounts of vertices and make a model so I can send models to the renderer.
Just use std::vector (you'll need to include <vector> first).
//this is in model class declaration
std::vector<GLfloat> vertices_;
std::vector<GLfloat> colors_;
//then in the constructor definition
Model::Model(const std::vector<GLfloat> &vertices, const std::vector<GLfloat> &colors) {
vertices_ = vertices;
colors_ = colors;
}
and then:
std::vector<GLfloat> vertices = {
//vertices here
};
std::vector<GLfloat> colors = {
//colors
};
mynamespace::Model cube(vertices,colors);
Of course, you can remove all the std::s if you have using std::vector; or using namespace std;
You get 4 bytes because when u pass the array to a function, the array degenerate into a Type * pointer. So u didn't get the length of array, instead u got the size of the pointer.
Since u have said u are new to both.
A simple way to work around is to def your fun
fun(Type array,int n)
When u invoke, you call like this:
fun(array,sizeof(array))
This should solve your problem.
Related
I'm trying to create a class for an "Entity" in Vulkan (An entity is a graphical object that can be rendered in a Window);
This class will contain the corresponding Vertex Buffer, along with the descriptor set layout, descriptor pool, descriptor sets and so on, the problem is how to manage the uniform buffers, because I'd like something like this:
class Entity final {
public:
enum class Uniform_Type : char {
MODEL_MATRIX, VIEW_MATRIX, PROJECTION_MATRIX, AMBIENT_VECTOR, DIFFUSE_VECTOR,
SPECULAR_VECTOR, SHININESS_FLOAT, LIGHT_AMBIENT_VECTOR, LIGHT_DIFFUSE_VECTOR,
LIGHT_SPECULAR_VECTOR, IS_LIGHT_SOURCE_BOOLEAN, LIGHT_POSITION_VECTOR,
VIEW_POSITION_VECTOR
};
// Private fields
std::unordered_map<Uniform_Type, std::pair<WHAT_HERE, std::vector<Uniform_Buffer>>> uniformsMap;
};
so if my class only needs the model, view and projection matrix, I'll do something like this (First element of the std::pair will hold the corresponding object (A matrix in this case), the second one is a vector of Uniform Buffers so they can be as much as the number of images in the swapchain):
uniformsMap[MODEL_MATRIX] = { glm::mat4(1.0f), std::vector<Uniform_Buffer>() };
uniformsMap[VIEW_MATRIX] = { glm::mat4(1.0f), std::vector<Uniform_Buffer>() };
uniformsMap[PROJECTION_MATRIX] = { glm::mat4(1.0f), std::vector<Uniform_Buffer>() };
The problem is that there are various kind of Uniform Buffers (matrix, vector, float, bool, etc...) so I'm stuck on what to write as the first element of the std::pair object.
Thanks for your time.
You can use std::variant<> that you then pull down to the correct type with get<>() when you need it.
The template would then be a list of all possible types you will need it to contain.
Also, this is a more a style thing but, I'm not a fan of using std::pair like that. It's very little effort to make a small struct with dedicated field names (other than thinking up the names). And you won't have to deal with std::pair's peculiarities.
So I'm using SFML for a Computer Science project - making a chess game. I have a class Square which is a single square of the chessboard - currently, it contains four vertices (four sf::Vertex objects in a member variable sf::VertexArray) and is colored either white or black. A class ChessBoard encapsulates a std::vector of Squares.
Using the tutorial given by SFML, I'm able to draw a single square. However, the draw() function works based on vertices, and since the ChessBoard class doesn't not actually contain vertices, but rather objects that themselves contain vertices, I'm not able to draw the chess board (i.e. its internal draw() function does not work).
Does anyone know how to work around this?
(I can provide more info/clarification/code if necessary/helpful.)
That's not really how "higher level drawing" is supposed to work.
Your parent class(es) shouldn't have to bother how to draw children. You're mixing responsibilities.
Instead, subclass sf::Drawable (and sf::Transformable, if required).
All this does is forcing you to implement a draw() member, which does all the drawing.
Here's a simple example for your ChessBoard class:
class ChessBoard : public sf::Drawable {
void draw (RenderTarget &target, RenderStates states) const {
for (auto &tile : mTiles) // Iterate over all board pieces
target.draw(tile, states); // Draw them
}
}
As you can see, this is trivial to setup. In a similar way, you can overload your Square class. (Isn't that name too generic? Why not simply reusing sf::RectangleShape?)
class ChessBoard : public sf::Drawable {
void draw (RenderTarget &target, RenderStates states) const {
target.draw(mVertices, states);
}
}
So, back to your main game loop. How to draw the ChessBoard? Again, trivial:
while (window.isOpen()) {
// All the other things happening
window.draw(mChessBoard);
}
While the advantages of this approach might not be as obvious at first, it's pretty easy to see that you're capable of passing responsibilities down the line. For example, the ChessBoard doesn't have to know how to properly draw a Square. In a trivial example – using unicolored polygons only – it's not that easy to notice, but your code will be a lot cleaner once you start adding shaders, textures, etc. Suddenly you'd no longer just have to return a sf::VertexArray, but you'll also need pointers or references to the other ressources. So the ChessBoard would have to know, which components to request from Square to draw it properly (Does it have a shader? Do I need a texture?).
Nevermind. Silly me. Implemented a getter inside class Square that returned the vertex array, & inside Chessboard looped through the vector of squares, calling the getter on each iteration.
Iam new to OpenGL and also new to C++ .
I created a main.cpp where i do everything .I Create an GLfloat data[] where i store my Cube's Vertices and also one GLfloat color[] for the Color. I create a VAO and a VBO and i have method, where i compile a simple Vertex and Fragment Shader.
The problem is,that my Code is very long,so i thought about creating a Cube Class,Triangle Class and so on.
My Question is now, can i use the same VAO for several Objects or do i use a new VAO for each Object?.
The other thing is, that i dont exactly know how to program this.I'am missing the structure(I used Java before).
My thoughts were :
class Cube {
public:
Cube();
Cube(GLfloat position[],GLfloat color[]);
//But i need the same Shaders for each Object , so do i initialize it here or somewhere else?
compileShader();
drawCube();
}
Note that this are only my thoughts about it..Maybe someone can help me out with this :)
VAO and VBO can be reused but for performance only should be if they aren't changing (for example, if you're keeping a 1x1x1 cube but using transformations to draw additional ones).
For a simple cube in a small application Your ideal structure would be something like
class Cube{
private static int vbo;
private static int vao;
public Cube(){
//If vbo and vao are 0 initialize them here
}
public void render(mat4* transform){
}
}
The shader would be a separate class, which can either be part of the rendering call for this object public void render (mat4* transform, shader* shader) or can be called by the main pipeline.
Now, I would recommend reading about header files in c++. In c++ headers are the right way to develop especially if you are going to be sharing your class around your program. Other classes need to only inherit the header, they don't have to care about the implementation, and that way your code only gets compiled once and you're using the same compiled assembly code throughout your class. (In c++ if you include actual code, it gets compiled, and even though modern linkers are good about merging duplicate code, it's still bad practice)
Cube.h:
class Cube{
static int vbo;
static int vao;
public:
Cube();
void render(mat4* transform);
}
cube.cpp:
Cube::Cube(){
//Initialize Here
}
Cube::render(mat4* transform){
//Render here
}
Then you'd also want a pair for shader
shader.h:
class Shader{
int ProgramID;
public:
Shader();
void activate ();
}
shader.cpp:
Shader::Shader(){
//compile shader here
}
Shader::activate(){
//make this shader program active here
}
The mat4 data for the transform that I mentioned came from http://glm.g-truc.net/0.9.6/index.html which is a great library for handling the math of 3d graphics.
If you want to refactor this further, you can define the render function of cube in an interface that all of your graphic objects will inherit, allowing you to more dynamically instantiate and configure the objects, and not care about what types they are, just that they're of the interface required.
Newbie...
I want to create a dynamicly growing list that will hold Point variables, a couple of int variables and whatever the colour variable is for Argb.
I'm doing it in Visual Studio C++ 2010
What is the best approach to handle this data within the program? It needs to store location, size and colour of objects that the user makes on the screen so I can draw them back to the Form when I refresh the Form. Currently I have a really nice program that draws squares,circles and lines in different colours and I can move that object around but this is only because I'm still holding onto the current object/shape data.
Create a struct or class to hold the information for one shape, and then use an std::vector to hold a list of them.
std::vector<Shape> myShapes;
If all of your shapes can be described by essentially the same data set, with some variance in size of some pieces of data, e.g the number of "Point varaibles" changes from shape to shape, then have a std::vector inside the shape class to hold them that variable data, e.g:
struct coordinate2D
{
int x;
int y;
};
class Shape
{
coordinate2D position; //the location on the shape
std::vector<coordinate2D> points; // the coordinates of the vertices that make up this shape.
};
//elsewhere
std::vector<Shape> myShapes;
I am making a basic render engine.
In order to let the render engine operate on all kinds of geometry,
I made this class:
class Geometry
{
protected:
ID3D10Buffer* m_pVertexBuffer;
ID3D10Buffer* m_pIndexBuffer;
public:
[...]
};
Now, I would like the user to be able to create his own geometry by inheriting from this class.
So let's suppose the user made a class Cube : public Geometry
The user would have to create the vertexbuffer and indexbuffer at initialisation.
This is a problem, since it would recreate the vertexbuffer and indexbuffer each time a new Cube object is made. There should only be one instance of vertexbuffer and indexbuffer per derived class. Either that, or a completely different design.
A solution might be to make separate static ID3D10Buffer* for the inheriting class , and set the pointers of the inherited class equal to those in the constructor.
But that would require a static method like static void CreateBuffers() which the user would have to call explicitly one time in his application for each type he decides to make that inherits from Geometry. That doesn't seem like a nice design.
What is a good solution to this problem?
You should separate the concept of an instance from the concept of a mesh. This means you create one version of the Geometry for a cube that represents the vertex and index buffer for a cube.
You then introduce a new class called GeometryInstance which contains a transformation matrix. This class should also have a pointer/reference to a Geometry. Now you can create new Instances of your geometry by creating GeometryInstances that all refer the same Geometry object not duplicating memory or work when creating a new box.
EDIT:
Given that you have the Geometry class from the question and a Mesh class as in your comment your Mesh class should look something like this:
class Mesh {
private:
Matrix4x4 transformation;
Geometry* geometry;
public:
Mesh(const Matrix4x4 _t, Geometry* _g) : transformation(_t), geometry(_g) {}
}
Now when creating your scene you want to do things like this
...
std::vector<Mesh> myMeshes;
// OrdinaryGeometry is a class inheriting Geometry
OrdinaryGeometry* geom = new OrdinaryGeometry(...);
for(int i = 0; i < ordinaryGeomCount; ++i) {
// generateTransform is a function that generates some
// transformation Matrix given an index, just as an example
myMeshes.push_back(Mesh(generateTransform(i), geom);
}
// SpecialGeometry is a class inheriting Geometry with a different
// set of vertices and indices
SuperSpecialGeometry* specialGeom = new SuperSpecialGeometry(...);
for(int i = 0; i < specialGeomCount; ++i) {
myMeshes.push_back(Mesh(generateTransform(i), specialGeom);
}
// Now render all instances
for(int i = 0; i < myMeshes.size(); ++i) {
render(myMeshes[i]);
}
Note how we only have two Geometry objects that are shared between multiple Meshes. These should ideally be refcounted using std::shared_ptr or something similar but it's outside the scope of the question.
What would be the point of sub classing Geometry in your cube example? A cube is simply an instance of Geometry which has a certain set of triangles and indices. There would be no difference between a Cube class and a Sphere class, other than that they fill their triangle/index buffers with different data. So the data itself is what is important here. You need a way to allow the user to provide your engine with various shape data, and to then refer to that data in some way once its made.
For providing shape data, you have two options. You can decide to either keep the details of Geometry private, and provide some interface that takes raw data like a string from a file, or a float array filled in some user made function, creates a Geometry instance for that data, and then gives the user some handle to that instance (or allow the user to specify a handle). Or, you can create some class like GeometryInfo which has methods addTriangle, addVertex etc which the user fills him/herself, and then have some function that accepts a GeometryInfo, creates a Geometry instance for that data and then gives the user some handle again.
In both situations you need to provide some interface that allows the user to say "here's some data, make something out of it and give it some handle. Minimally it would have a function as I described. You would need to maintain a map somewhere of created Geometry instances in your engine. This is so you enforce your one instance per shape rule, and so you can associate what the user wants ("Ball", "Cube") with what your engine needs (Geometry with filled buffers).
Now about the handle. I would either let the user associate the data with a name, like "Ball", or return some integer that the user would then associate with a certain "Ball" instance. That way when you make your Rocket class, the user can then request the "Ball" instance from your engine, various other objects can use the "Ball" and everything's fine because they're just storing handles, not the ball itself. I wouldn't advise storing a pointer to the actual Geometry instance. The mesh doesn't own the geometry, because it can share it with other meshes. It doesn't need access to the geometry's members, because the renderer handles the grunt work. So it is an unnecessary dependency. The only reason would be for speed, but using hashing for your handles would work just as good.
Now for some examples:
Providing shape data:
//option one
engine->CreateGeometryFromFile("ball.txt", "Ball");
//option two
GeometryInfo ball;
ball.addTriangle(0, 1, 0, 1);
ball.addTriangle(...);
...
engine->CreateGeometryFromInfo(ball, "Ball");
Refering to that data using a handle:
class Drawable
{
std::string shape;
Matrix transform;
};
class Rocket : public Drawable
{
Rocket() { shape = "Ball";}
//other stuff here for physics maybe
};
class BallShapedEnemy : public Drawable
{
BallShapedEnemy() { shape = "Ball";}
...
}
...
...in user's render loop...
for each (drawable in myDrawables)
{
engine->Render(drawable.GetShape(), drawable.GetTransform());
}
Now, having a separate class for each different game object such as Rocket is debatable, and is the subject of another question entirely, I was just making it look like your example from a comment.
This may be a sloppy way of doing it but could you not just make a singleton?
#pragma once
#include <iostream>
#define GEOM Geometry::getInstance()
class Geometry
{
protected:
static Geometry* ptrInstance;
static Geometry* getInstance();
float* m_pVertexBuffer;
float* m_pIndexBuffer;
public:
Geometry(void);
~Geometry(void);
void callGeom();
};
#include "Geometry.h"
Geometry* Geometry::ptrInstance = 0;
Geometry::Geometry(void)
{
}
Geometry::~Geometry(void)
{
}
Geometry* Geometry::getInstance()
{
if(ptrInstance == 0)
{
ptrInstance = new Geometry();
}
return ptrInstance;
}
void Geometry::callGeom()
{
std::cout << "Call successful!" << std::endl;
}
Only problem with this method is you would only ever have one Geometry object and I'm assuming you might want more than one? If not it could be useful, but I think Lasserallan's method is probably a much better implementation for what your looking for.