Undefined reference to a static const struct - c++

I have this header (with hidden code):
class DrawBuffers
{
public:
struct CubeCorners
{
GLfloat corners[NUM_VERTS * ELEM_PER_NORM];
CubeCorners(bool normalize);
};
static const CubeCorners POSITIONS;
static const GLfloat COLOR_DEFAULT[ELEM_PER_COLOR];
static const CubeCorners NORMALS;
static const GLuint INDICES[NUM_INDICES / NB_FACES][NB_INDICES_PER_FACE];
};
I have this in the cpp:
const DrawBuffers::CubeCorners POSITIONS = DrawBuffers::CubeCorners(false);
const GLfloat DrawBuffers::COLOR_DEFAULT[] = {1.f, 1.f, 1.f, 1.f};
const DrawBuffers::CubeCorners NORMALS = DrawBuffers::CubeCorners(true);
const GLuint DrawBuffers::INDICES[][NB_INDICES_PER_FACE] = { //second indices
{0, 1, 2, // Back
2, 3, 0},
{7, 6, 5, // Front
5, 4, 7},
{4, 5, 1, // Left
1, 0, 4},
{3, 2, 6, // Right
6, 7, 3},
{4, 0, 3, // Bottom
3, 7, 4},
{6, 2, 1, // Top
1, 5, 6}};
And I still get an undefined reference to POSITIONS in the same .cpp file... Anything I may have forgotten?
Thank you! :)

These are static members, so you need to qualify the names in their definitions (as you've already done with two of them):
const DrawBuffers::CubeCorners DrawBuffers::POSITIONS = DrawBuffers::CubeCorners(false);
^^^^^^^^^^^^^
You've instead declared static non-member variables.

Related

C++ GLFloat arrays within an array

Trying to create an array of type GLFloat which contains arrays of type GLFloat.
GLfloat p0[] = { -3, 0, -3};
GLfloat p1[] = { 3, 0, -3};
GLfloat points[2][3] = {p0, p1};
Error message: Type GLFloat cannot be used to an entity of type GLFloat
You could create the matrix directly.
GLfloat points[2][3] = {{-3, 0, -3}, { 3, 0, -3}};
If you want to use braced initialisation the way to go would be
points[2][3] = { {-3, 0, -3}, {3, 0, -3} };
Why your way doesn't work:
points[2][3] = { p0, p1 };
What happens is that p0 decays to float* and so does p1 which you cannot assign to float.
Another option would be with memcpy:
std::memcpy(&points[0], &p0, 3 * sizeof(float));
std::memcpy(&points[1], &p1, 3 * sizeof(float));
But I'm not a fan of all this address manipulation and memcpy when using C++

glClear() keeps the screen black

I'm developing a 2D game called Spaceland and I've ran into a problem with clearing the screen. Whenever I call glClear(GL_COLOR_BUFFER_BIT) every frame, it keeps my screen black until i stop calling it. I have tested this by assigning glClear() to a key, and when I hold it down the screen turns black, when not pressed, the quad that is spreading across the screen just grows until I clear again.
I am using glClearColor(0, 0, 0, 1) when I create a window. I have tried turning off and on glfwSwapInterval().
create() function in my Window class:
public void create(boolean vsync) {
GLFWErrorCallback.createPrint(System.err).set();
GLFWVidMode vid = glfwGetVideoMode(glfwGetPrimaryMonitor());
keys = new boolean[GLFW_KEY_LAST];
for (int i = 0; i < GLFW_KEY_LAST; i ++) {
keys[i] = false;
}
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
ID = glfwCreateWindow(vid.width(), vid.height(), TITLE, glfwGetPrimaryMonitor(), 0);
if (ID == 0)
throw new IllegalStateException("Error whilst creating window: '" + TITLE + "'");
glfwMakeContextCurrent(ID);
createCapabilities();
glClearColor(0, 0, 0, 1);
camera = new Camera(getWidth(), getHeight());
glfwSwapInterval(vsync ? 1 : 0);
}
Sprite Class:
public class Sprite {
private VertexArray vao;
private VertexBuffer
pVbo,
iVbo;
private int vertexCount;
private float scale;
private Vector3f position;
private Vector3f rotation;
private Matrix4f tMatrix;
public Sprite(float[] pos, int[] indices) {
vertexCount = indices.length;
position = new Vector3f(0, 0, 0);
rotation = new Vector3f(0, 0, 0);
scale = 0.1f;
tMatrix = MatrixHelper.createTransformationMatrix(position, rotation, scale);
vao = new VertexArray();
pVbo = new VertexBuffer(false);
iVbo = new VertexBuffer(true);
vao.bind();
pVbo.bind();
pVbo.add(pos);
vao.add();
pVbo.unbind();
iVbo.bind();
iVbo.add(indices);
iVbo.unbind();
vao.unbind();
}
public void setPosition(float x, float y, float z) {
position.x = x;
position.y = y;
position.z = z;
}
public void setRotation(Vector3f rot) {
rotation = rot;
}
public void render(int renderType) {
MatrixHelper.setTMatrixPosition(tMatrix, position);
setPosition(getPosition().x + 0.0001f, 0, 0);
System.out.println(tMatrix);
Spaceland.shader.bind();
Spaceland.shader.editValue("transformation", tMatrix);
vao.bind();
glEnableVertexAttribArray(0);
iVbo.bind();
glDrawElements(renderType, vertexCount, GL_UNSIGNED_INT, 0);
iVbo.unbind();
glDisableVertexAttribArray(0);
vao.unbind();
Spaceland.shader.unbind();
}
public Vector3f getPosition() {
return position;
}
}
I don't think you need to see my Camera class or MatrixHelper class as the problem has occured before implementing this.
Main class (ignore rose[] and roseI[] it's just a cool pattern I made as a test):
public class Spaceland {
public static Window window;
public static Sprite sprite;
public static Shader shader;
public static float[] rose = {
-0.45f, 0f,
0.45f, 0f,
0f, 0.45f,
0f, -0.45f,
-0.4f, -0.2f,
-0.4f, 0.2f,
0.4f, -0.2f,
0.4f, 0.2f,
-0.2f, -0.4f,
-0.2f, 0.4f,
0.2f, -0.4f,
0.2f, 0.4f
};
public static int[] roseI = {
0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11,
1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11,
2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9, 2, 10, 2, 11,
3, 4, 3, 5, 3, 6, 3, 7, 3, 8, 3, 9, 3, 10, 3, 11,
4, 5, 4, 6, 4, 7, 4, 8, 4, 9, 4, 10, 4, 11,
5, 6, 5, 7, 5, 8, 5, 9, 5, 10, 5, 11,
6, 7, 6, 8, 6, 9, 6, 10, 6, 11,
7, 8, 7, 9, 7, 10, 7, 11,
8, 9, 8, 10, 8, 11,
9, 10, 9, 11,
10, 11,
};
public static float[] quad = {
0.5f, 0.5f,
0.5f, -0.5f,
-0.5f, 0.5f,
-0.5f, -0.5f
};
public static int[] quadI = {
2, 0, 3,
0, 1, 3
};
public static void main(String[] args) {
init();
}
public static void loop() {
while (!window.isCloseRequested()) {
update();
render();
}
destroy(0);
}
public static void init() {
if (!glfwInit())
throw new IllegalStateException("Error whilst initialising GLFW");
window = new Window("Spaceland");
window.create(true);
shader = new Shader("src/main/java/com/spaceland/graphics/fragment.fs", "src/main/java/com/spaceland/graphics/vertex.vs");
sprite = new Sprite(quad, quadI);
loop();
}
public static void render() {
window.render();
sprite.render(GL11.GL_TRIANGLES);
}
public static void update() {
window.update();
if (window.isDown(GLFW_KEY_SPACE)) {
glClear(GL_COLOR_BUFFER_BIT);
}
}
public static void destroy(int error) {
window.destroy();
glfwTerminate();
glfwSetErrorCallback(null).free();
shader.destroy();
VertexBuffer.deleteAll();
VertexArray.destroyAll();
System.exit(error);
}
}
Please tell me if you need to see the Shader class, shader vs and fs files, or anything else.
Thanks!
glClear affects the output buffers. So it is part of rendering. If you want to clear as part of your rendering, put glClear inside your render function.
You have it inside update. I suspect that whomever is calling render and update (LWJGL, presumably?) doesn't guarantee any particular ordering to them. So each time you're asked to update you're stomping on top of the last thing you rendered.
Updates:
adjust internal state, usually partly as a function of time.
Renders:
capture current state visually.
It is not very clear in my question, but the answer is that I cleared the screen, swapped buffers, rendered, etc. Which doesn't work.
glClear(...);
glfwSwapBuffers(...);
...render...
This is how it is currently, and this doesn't work.
glClear(...);
...render...
glfwSwapBuffers(...);
This is how I do it now, and it works fine.

Incorrectly rendering Isocahedron in OpenGL

I'm trying to draw an Isocahedron in OpenGL with c++. I keep getting close but having some missing faces. I have found 3 different sets of vertex/index data on multiple sites, most often the data listed below
float X = 0.525731112119133606f;
float Z = 0.850650808352039932f;
float temppts[12][3] = { { -X, 0.0f, Z }, { X, 0.0f, Z }, { -X, 0.0f, -Z }, { X, 0.0f, -Z },
{ 0.0f, Z, X }, { 0.0f, Z, -X }, { 0.0f, -Z, X }, { 0.0f, -Z, -X },
{ Z, X, 0.0f }, { -Z, X, 0.0f }, { Z, -X, 0.0f }, { -Z, -X, 0.0f } };
GLushort tempindicies[60] =
{ 1, 4, 0, 4, 9, 0, 4, 5, 9, 8, 5, 4, 1, 8, 4,
1, 10, 8, 10, 3, 8, 8, 3, 5, 3, 2, 5, 3, 7, 2,
3, 10, 7, 10, 6, 7, 6, 11, 7, 6, 0, 11, 6, 1, 0,
10, 1, 6, 11, 0, 9, 2, 11, 9, 5, 2, 9, 11, 2, 7};
This code is adapted from a book and multiple sites display it working, though they are drawing immediate and I'm using vbo/ibo. Can anyone point me to some working vertex/index data or tell me what is going wrong transferring this to buffer objects? The three different data all have differently incorrect icosahedrons, each with different faces missing.
I have checked over my bufferData calls many times and tried several drawing modes ( TRIANGLES, TRIANGLE_STRIP ... ) and am convinced the index data is wrong somehow
I used the mesh coordinates (vertices) and the triangle connectivity from Platonic Solids (scroll down to icosahedron). I've pasted a screen shot from that file below. When calling glDrawElements I used GL_TRIANGLES.
Icosahedron
Another thing to watch out for is back face culling. Initially switch off backface culling.
glDisable(GL_CULL_FACE);

Is it possible to use a vector for opengl vertex array?

I want my class Vector3f to store index pointes for my cuboid (made from triangles).
Heres what I would push to the vector.
vector<Vector3f> I;
I.push_back(Vector3f(1, 0, 2)); //front
I.push_back(Vector3f(2, 0, 3));
I.push_back(Vector3f(4, 5, 7)); //back
I.push_back(Vector3f(7, 5, 6));
I.push_back(Vector3f(0, 4, 3)); //left
I.push_back(Vector3f(3, 4, 7));
I.push_back(Vector3f(5, 1, 6)); //right
I.push_back(Vector3f(6, 1, 2));
I.push_back(Vector3f(7, 6, 3)); //up
I.push_back(Vector3f(3, 6, 2));
I.push_back(Vector3f(1, 0, 5)); //down
I.push_back(Vector3f(5, 0, 4));
Can vertex arrays read from classes?
Assuming your Vector3f is POD
&I[0] will give your a float * which you can pass to glBufferData

Procedural generation of wall textures, dividing a pair of triangles (recursively?)

If I make a really simple game that puts the player in a tunnel with square walls made of two triangles (and I have) the walls look a bit boring and even disorienting at certain angles. I'm thinking about taking the data that defines the square panels and procedurally generating a more interesting texture by subdividing each triangle further before randomly perturbing the Z values to get some depth in the wall.
The two triangles look like:
typedef struct {
float Position[3];
float Color[4];
float TexCoord[2];
float Normal[3];
} Vertex;
const Vertex Vertices[] = {
// Front
{{0, 0, 0}, {1, 0, 0, 1}, {1, 0}, {0, 0, 1}},
{{1, 0, 0}, {1, 0, 0, 1}, {1, 1}, {0, 0, 1}},
{{1, 1, 0}, {1, 0, 0, 1}, {0, 1}, {0, 0, 1}},
{{0, 1, 0}, {1, 0, 0, 1}, {0, 0}, {0, 0, 1}}
};
This square is transformed into any necessary position to make walls, floor, ceiling.
I can put a texture onto the wall but when looking at the wall from side on (strafing) it is obviously perfectly flat. Modern hardware has triangles to burn so that's why I'm thinking along these lines.
Looks like a job for a recursive algorithm. One problem though, when it comes to the corners the Z values all have to come back to zero or the panels won't tile in 3D and the player will see through the corner gaps where they shouldn't. Simply ruling the edge Z values out of the random process is probably not going to look great - unless maybe all the Z values are changed only by positive values, possibly producing a rough-hewn stone block effect? Knowing which face is forward is obviously important so that seems like one workable solution.
Have you done this kind of procedural generation and if so how did you achieve depth in your walls and how did you handle the panel joins?