Align a matrix to a vector in OpenGL - c++

I'm trying to visualize normals of triangles.
I have created a triangle to use as the visual representation of the normal but I'm having trouble aligning it to the normal.
I have tried using glm::lookAt but the triangle ends up in some weird position and rotation after that. I am able to move the triangle in the right place with glm::translate though.
Here is my code to create the triangle which is used for the visualization:
// xyz rgb
float vertex_data[] =
{
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.25f, 0.0f, 0.025f, 0.0f, 1.0f, 1.0f,
0.25f, 0.0f, -0.025f, 0.0f, 1.0f, 1.0f,
};
unsigned int index_data[] = {0, 1, 2};
glGenVertexArrays(1, &nrmGizmoVAO);
glGenBuffers(1, &nrmGizmoVBO);
glGenBuffers(1, &nrmGizmoEBO);
glBindVertexArray(nrmGizmoVAO);
glBindBuffer(GL_ARRAY_BUFFER, nmrGizmoVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, nrmGizmoEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index_data), index_data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
and here is the code to draw the visualizations:
for(unsigned int i = 0; i < worldTriangles->size(); i++)
{
Triangle *tri = &worldTriangles->at(i);
glm::vec3 wp = tri->worldPosition;
glm::vec3 nrm = tri->normal;
nrmGizmoMatrix = glm::mat4(1.0f);
//nrmGizmoMatrix = glm::translate(nrmGizmoMatrix, wp);
nrmGizmoMatrix = glm::lookAt(wp, wp + nrm, glm::vec3(0.0f, 1.0f, 0.0f));
gizmoShader.setMatrix(projectionMatrix, viewMatrix, nrmGizmoMatrix);
glBindVertexArray(nrmGizmoVAO);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
When using only glm::translate, the triangles appear in right positions but all point in the same direction. How can I rotate them so that they point in the direction of the normal vector?

Your code doesn't work because lookAt is intended to be used as the view matrix, thus it returns the transform from world space to local (camera) space. In your case you want the reverse -- from local (triangle) to world space. Taking an inverse of lookAt should solve that.
However, I'd take a step back and look at (haha) the bigger picture. What I notice about your approach:
It's very inefficient -- you issue a separate call with a different model matrix for every single normal.
You don't even need the entire model matrix. A triangle is a 2-d shape, so all you need is two basis vectors.
I'd instead generate all the vertices for the normals in a single array, and then use glDrawArrays to draw that. For the actual calculation, observe that we have one degree of freedom when it comes to aligning the triangle along the normal. Your lookAt code resolves that DoF rather arbitrary. A better way to resolve that is to constrain it by requiring that it faces towards the camera, thus maximizing the visible area. The calculation is straightforward:
// inputs: vertices output array, normal position, normal direction, camera position
void emit_normal(std::vector<vec3> &v, const vec3 &p, const vec3 &n, const vec3 &c) {
static const float length = 0.25f, width = 0.025f;
vec3 t = normalize(cross(n, c - p)); // tangent
v.push_back(p);
v.push_back(p + length*n + width*t);
v.push_back(p + length*n - width*t);
}
// ... in your code, generate normals through:
std::vector<vec3> normals;
for(unsigned int i = 0; i < worldTriangles->size(); i++) {
Triangle *tri = &worldTriangles->at(i);
emit_normal(normals, tri->worldPosition, tri->normal, camera_position);
}
// ... create VAO for normals ...
glDrawArrays(GL_TRIANGLES, 0, normals.size());
Note, however, that this would make the normal mesh camera-dependent -- which is desirable when rendering normals with triangles. Most CAD software draws normals with lines instead, which is much simpler and avoids many problems:
void emit_normal(std::vector<vec3> &v, const vec3 &p, const vec3 &n) {
static const float length = 0.25f;
v.push_back(p);
v.push_back(p + length*n);
}
// ... in your code, generate normals through:
std::vector<vec3> normals;
for(unsigned int i = 0; i < worldTriangles->size(); i++) {
Triangle *tri = &worldTriangles->at(i);
emit_normal(normals, tri->worldPosition, tri->normal);
}
// ... create VAO for normals ...
glDrawArrays(GL_LINES, 0, normals.size());

Related

Why is my Index Generation Function not correctly building the triangle primitives?

I am trying to code a function which automatically populates a mesh's index vector container. The function should work without issue in theory as it generates the proper indices in their correct order; however, the triangles do not form! Instead, I am left with a single line.
My mesh generation code is supposed to build an octahedron and then render it in the main game loop. The mesh class is shown below in its entirety:
struct vertex
{
glm::vec3 position;
glm::vec3 color;
};
class Mesh
{
public:
GLuint VAO, VBO, EBO;
std::vector <vertex> vtx;
std::vector <glm::vec3> idx;
glm::mat4 modelMatrix = glm::mat4(1.f);
Mesh(glm::vec3 position, glm::vec3 scale)
{
vertexGen(6);
idx = indexGen(6);
modelMatrix = glm::scale(glm::translate(modelMatrix, position), scale);
initMesh();
};
void Render(Shader shaderProgram, Camera camera, bool wireframe)
{
glUseProgram(shaderProgram.ID);
glPatchParameteri(GL_PATCH_VERTICES, 3); // Indicates to the VAO that each group of three vertices is one patch (triangles)
glProgramUniformMatrix4fv(shaderProgram.ID, 0, 1, GL_FALSE, glm::value_ptr(modelMatrix));
glProgramUniformMatrix4fv(shaderProgram.ID, 1, 1, GL_FALSE, glm::value_ptr(camera.camMatrix));
glProgramUniform3fv(shaderProgram.ID, 2, 1, glm::value_ptr(camera.Position));
glBindVertexArray(VAO); // Binds the VAO to the shader program
if (wireframe)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDisable(GL_CULL_FACE);
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glEnable(GL_CULL_FACE);
}
glDrawElements(GL_PATCHES, idx.size(), GL_UNSIGNED_INT, 0); // Tells the shader program how to draw the primitives
}
private:
void vertexGen(int n) {
// Populate the base six vertices
vtx.push_back(vertex{ glm::vec3( 0.0f, 0.5f, 0.0f), glm::vec3(0.f, 1.f, 0.f) });
vtx.push_back(vertex{ glm::vec3(-0.5f, 0.0f, 0.0f), glm::vec3(0.f, 1.f, 0.f) });
vtx.push_back(vertex{ glm::vec3( 0.0f, 0.0f, -0.5f), glm::vec3(0.f, 1.f, 0.f) });
vtx.push_back(vertex{ glm::vec3( 0.5f, 0.0f, 0.0f), glm::vec3(0.f, 1.f, 0.f) });
vtx.push_back(vertex{ glm::vec3( 0.0f, 0.0f, 0.5f), glm::vec3(0.f, 1.f, 0.f) });
vtx.push_back(vertex{ glm::vec3( 0.0f,-0.5f, 0.0f), glm::vec3(0.f, 1.f, 0.f) });
}
std::vector<glm::vec3> indexGen(int n) {
std::vector<glm::vec3> indices;
// Calculate the indices for the top 4 triangles
indices.push_back(glm::vec3( 0, n - 5, n - 4 ));
indices.push_back(glm::vec3( 0, n - 4, n - 3 ));
indices.push_back(glm::vec3( 0, n - 3, n - 2 ));
indices.push_back(glm::vec3( 0, n - 2, n - 5 ));
// Calculate the indices for the bottom 4 triangles
indices.push_back(glm::vec3( 5, n - 5, n - 4));
indices.push_back(glm::vec3( 5, n - 4, n - 3));
indices.push_back(glm::vec3( 5, n - 3, n - 2));
indices.push_back(glm::vec3( 5, n - 2, n - 5));
return indices;
}
void initMesh()
{
glCreateVertexArrays(1, &VAO); // Sets the address of the uint VAO as the location of a gl vertex array object
glCreateBuffers(1, &VBO); // Sets the address of the uint VBO as the location of a gl buffer object
glCreateBuffers(1, &EBO); // Sets the address of the uint EBO as the location of a gl buffer object
glNamedBufferData(VBO, vtx.size() * sizeof(vtx[0]), vtx.data(), GL_STATIC_DRAW); // Sets the data of the buffer named VBO
glNamedBufferData(EBO, idx.size() * sizeof(idx[0]), idx.data(), GL_STATIC_DRAW); // Sets the data of the buffer named EBO
glEnableVertexArrayAttrib(VAO, 0); // Enables an attribute of the VAO in location 0
glEnableVertexArrayAttrib(VAO, 1); // Enables an attribute of the VAO in location 1
glVertexArrayAttribBinding(VAO, 0, 0); // Layout Location of Position Vectors
glVertexArrayAttribBinding(VAO, 1, 0); // Layout Location of Color Values
glVertexArrayAttribFormat(VAO, 0, 3, GL_FLOAT, GL_FALSE, 0); // Size, and Type of Position Vectors
glVertexArrayAttribFormat(VAO, 1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat)); // For the Color Values
glVertexArrayVertexBuffer(VAO, 0, VBO, 0, 6 * sizeof(GLfloat)); // Sets the VBO to indicate the start, offset, and stride of vertex data in the VAO
glVertexArrayElementBuffer(VAO, EBO); // Sets the EBO to index the VAO vertex connections
}
};
I took this problem step by step and did all of the basic math on paper. The index generation function returns the expected indices in their correct order as just having the indices written out, but it differs in that the written-out indices generate the desired result whereas the generation function only produces a single line when rendered:
I suspect that the issue lies in my mesh initialization function (initMesh), specifically in the glNamedBufferData or glVertexArrayVertexBuffer, but my knowledge of the functions is very limited. I tried changing the parameter of the glNamedBufferData function to different variations of idx.size()*sizeof(idx[0].x), but that yielded the same results, so I am at a loss. Could someone help me fix this, please?
glm::vec3 is a vector of floats (I think) but you are telling OpenGL to read them as unsigned ints.
Float 0.0 is 0x00000000 (i.e. same as int 0), but float 1.0 is 0x3f800000 (same as int 1065353216). They aren't compatible ways to store numbers. You could try glm::ivec3 which is a vector of ints, but I think most people would use std::vector<int> (or unsigned int) and use 3 entries per triangle.
I think it's okay in this case, but I don't like to use types like ivec3 when I mean to have 3 separate ints isn't always a good practice, because the compiler can insert padding in unexpected places. It's possible that on some platforms, ivec3 could be 3 ints and an extra 4 bytes of padding, making 16 bytes in total, and the extra padding bytes throw off the layout you're relying on. glDrawArrays wouldn't skip over padding after every 3 indices and there would be no way to tell it to do that. It's okay for vertices, since you can tell OpenGL exactly where the data is.

OpenGL doesn't draw my Quad. Everything seems to be fine. No errors from OpenGL

I'm trying to make a system that allows you to type in a position and scale and it will create a vector that automatically generates all the vertices. The problem is when I try to draw my object it just won't show up. I have used OpenGL's built-in debugging system but it didn't say anything was wrong. So then I tried to manually debug myself but everything seemed to draw just fine.
Renderer::createQuad() method:
Shape Renderer::createQuad(glm::vec2 position, glm::vec2 scale, Shader shader, Texture texture)
{
float x = position.x;
float y = position.y;
float width = scale.x;
float height = scale.y;
std::vector<float> vertices =
{
x+width, y+height, 1.0f, 1.0f, // TR
x+width, y-height, 1.0f, 0.0f, // BR
x-width, y-height, 0.0f, 0.0f, // BL
x-width, y+height, 0.0f, 1.0f // TL
};
std::vector<uint32_t> indices =
{
0, 1, 3,
1, 2, 3
};
m_lenVertices = vertices.size();
m_lenIndices = indices.size();
// these Create methods should be fine as OpenGL does not give me any error
// also I have another function that requires you to pass in the vertex data and indices that works just fine
// I bind the thing I am creating
createVAO();
createVBO(vertices);
createEBO(indices);
createTexture(texture);
createShader(shader.getVertexShader(), shader.getFragmentShader());
Shape shape;
glm::mat4 model(1.0f);
glUniformMatrix4fv(glGetUniformLocation(m_shader, "model"), 1, GL_FALSE, glm::value_ptr(model));
shape.setShader(m_shader);
shape.setVAO(m_VAO);
shape.setTexture(m_texture);
shape.setPosition(position);
return shape;
}
Renderer::draw() method:
void Renderer::draw(Shape shape)
{
if (!m_usingIndices)
{
// Unbinds any other shapes
glBindVertexArray(0);
glUseProgram(0);
shape.bindShader();
shape.bindVAO();
shape.bindTexture();
glDrawArrays(GL_TRIANGLES, 0, m_lenVertices);
}
else
{
// Unbinds any other shapes
glBindVertexArray(0);
glUseProgram(0);
shape.bindShader();
shape.bindVAO();
shape.bindTexture();
glDrawElements(GL_TRIANGLES, m_lenIndices, GL_UNSIGNED_INT, 0);
}
}
Projection matrix:
glm::mat4 m_projectionMat = glm::ortho(-Window::getWidth(), Window::getWidth(), -Window::getHeight(), Window::getHeight, 0.1f, 100.0f);
Creating then rendering the Quad:
// Creates the VBO, VAO, EBO, etc.
quad = renderer.createQuad(glm::vec2(500.0f, 500.0f), glm::vec2(200.0F, 200.0f), LoadFile::loadShader("Res/Shader/VertShader.glsl", "Res/Shader/FragShader.glsl"), LoadFile::loadTexture("Res/Textures/Lake.jpg"));
// In the main game loop we render the quad
quad.setCamera(camera); // Sets the View and Projection matrix for the quad
renderer.draw(quad);
Output:
Output of the code before

Troubles with laying out memory for use by OpenGL (glBufferSubData help needed)

So today I wanted to learn how I can use a Vector2 & Color class to send data to OpenGL with pretty clean looking syntax.
The plan is this.
/*
Vector2 (8 bytes)
Color (16 bytes)
Vector2 + Color = 24 bytes
How can memory be laid out like this?
{Vector2, Color},
{Vector2, Color},
{Vector2, Color}
*/
So I have my two arrays of data.
Vector2 vertices[] = {
Vector2(0.0f, 0.5f),
Vector2(0.5f, -0.5f),
Vector2(-0.5f, -0.5f)
};
// colors would be mapped to there respective indexes in the vertices array (i.e colors[0] is mapped to vertices[0])
Color colors[] = {
Color(1.0f, 0.3f, 0.3f),
Color(0.3f, 1.0f, 0.3f),
Color(0.3f, 0.3f, 1.0f)
};
I was able to get a regular triangle rendering at the correct points,
but sending over the color data has been pretty difficult for me to pull off.
The result I currently get is this.
Here's a snippet of the code.
// positions on screen
Vector2 vertices[] = {
Vector2(0.0f, 0.5f),
Vector2(0.5f, -0.5f),
Vector2(-0.5f, -0.5f)
};
// colors for each position
Color colors[] = {
Color(1.0f, 0.3f, 0.3f),
Color(0.3f, 1.0f, 0.3f),
Color(0.3f, 0.3f, 1.0f)
};
// create vertex and array buffers (each bound automatically)
unsigned int vertexArray = createVertexArray();
unsigned int vertexBuffer = createBuffer(GL_ARRAY_BUFFER);
// allocate the data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), nullptr, GL_STATIC_DRAW);
// fill up allocated memory
for (int i = 0; i < 3; ++i) {
glBufferSubData(GL_ARRAY_BUFFER, sizeof(Vector2) * i, sizeof(Vector2), &vertices[i]);
glBufferSubData(GL_ARRAY_BUFFER, (sizeof(Vector2) + sizeof(Color)) * (i + 1), sizeof(Color), &colors[i]);
}
// set up vertex attributes
glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(Vector2) + sizeof(Color), nullptr);
glVertexAttribPointer(1, 3, GL_FLOAT, false, sizeof(Vector2) + sizeof(Color), (const void*)( sizeof(Vector2) ));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
You need to add 1 vertex and 1 color alternately to the buffer:
for (int i = 0; i < 3; ++i)
{
GLintptr offsetV = i * (sizeof(Vector2) + sizeof(Color));
glBufferSubData(GL_ARRAY_BUFFER, offsetV, sizeof(Vector2), &vertices[i]);
GLintptr offsetC = offsetV + sizeof(Vector2);
glBufferSubData(GL_ARRAY_BUFFER, offsetC, sizeof(Color), &colors[i]);
}

How to build data for a tessellated rectangle

I am not able to figure out the function that would be required to build data for a tessellated rectangle.
Currently this is what i do for a non tessellated rectangle;
GLuint Waveindices[] = {
0, 1, 3,
1, 2, 3
};
std::vector<GLfloat> verticesRect;
verticesRect = {
// Positions // Normal Coords // Texture Coords
width, height, 0.0f, 0.0 , 0.0, 1.0 , 1.0f, 0.0f, // Top Right
width, -height, 0.0f, 0.0 , 0.0, 1.0 , 1.0f, 1.0f, // Bottom Right
-width, -height, 0.0f, 0.0 , 0.0, 1.0 , 0.0f, 1.0f, // Bottom Left
-width, height, 0.0f, 0.0 , 0.0, 1.0 , 0.0f, 0.0f // Top Left
glGenVertexArrays(1, &m_VAO);
glGenBuffers(1, &m_VBO);
glGenBuffers(1, &m_EBO);
glBindVertexArray(m_VAO);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, verticesRect.size() * sizeof(GLfloat), &verticesRect[0],
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Waveindices), Waveindices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
};
Apologies i don't have any code for the options which i tried as i just could not get any meaning full output from the code which i wrote.
This is how the rectangle should look like when Tessellation value is 2.
What you need is to linearly interpolate between the edge points ... compute x,y,z, set texture coordinate and once finished recompute normals using cross product. Then just create triangulation and render ...
Here simple C++ (old api) example:
GLfloat divide(GLfloat a,GLfloat b){ if (fabs(b)<1e-10) return 0.0; else return a/b; }
void normalize(GLfloat *c,GLfloat *a) // c = a/|a|
{
GLfloat l=divide(1.0,sqrt((a[0]*a[0])+(a[1]*a[1])+(a[2]*a[2])));
c[0]=a[0]*l;
c[1]=a[1]*l;
c[2]=a[2]*l;
}
void cross(GLfloat *c,GLfloat *a,GLfloat *b) // c = cross(a,b)
{
GLfloat q[3];
q[0]=(a[1]*b[2])-(a[2]*b[1]);
q[1]=(a[2]*b[0])-(a[0]*b[2]);
q[2]=(a[0]*b[1])-(a[1]*b[0]);
for(int i=0;i<3;i++) c[i]=q[i];
}
void genere(GLfloat w,GLfloat h)
{
const int m=16,n=16; // points per grid axis
const int n8=n*8; // size of VBO gfx data
const int sz0=m*n8; // size of VBO gfx data
const int sz1=(m-1)*(n-1)*6;// size of indices
GLfloat dat[sz0];
GLuint idx[sz1];
int i,j,k,a,b;
GLfloat x,y,z,dx,dy,l;
GLfloat u[3],v[3],nor[3];
// gfx data
dx=2.0*w/GLfloat(n-1);
dy=2.0*h/GLfloat(m-1);
for (a=0,y=-h,j=0;j<m;j++,y+=dy)
for ( x=-w,i=0;i<n;i++,x+=dx)
{
// Vertex
z=0.3*sin((x*x)+(y*y));
dat[a]=x; a++;
dat[a]=y; a++;
dat[a]=z; a++;
// Normal (will be recomputed latter)
dat[a]=0.0; a++;
dat[a]=0.0; a++;
dat[a]=1.0; a++;
// TexCoord
dat[a]=(x+w)/(w+w); a++;
dat[a]=(y+h)/(h+h); a++;
}
// triangulation indices
for (a=0,j=1;j<m;j++)
for ( i=1;i<n;i++)
{
// b = location of point[i,j] in dat[]
b=((n*j)+i)*8;
// first triangle per quad
idx[a]=b-8; a++;
idx[a]=b-8-n8; a++;
idx[a]=b; a++;
// second triangle per quad
idx[a]=b-8-n8; a++;
idx[a]=b-n8; a++;
idx[a]=b; a++;
// recompute inner normals
for (k=0;k<3;k++)
{
u[k]=dat[idx[a-6]+k]-dat[idx[a-4]+k];
v[k]=dat[idx[a-5]+k]-dat[idx[a-4]+k];
}
cross(nor,u,v); normalize(nor,nor);
for (k=0;k<3;k++)
{
u[k]=dat[idx[a-3]+k]-dat[idx[a-1]+k];
v[k]=dat[idx[a-2]+k]-dat[idx[a-1]+k];
}
cross(u,u,v); normalize(u,u);
for (k=0;k<3;k++) dat[idx[a-1]+3+k]=0.5*(nor[k]+u[k]);
}
// copy edge normals
for (j=0,i=1;i<n;i++)
{
// b = location of point[i,j] in dat[]
b=((n*j)+i)*8;
// copy
for (k=0;k<3;k++) dat[b+3+k]=dat[b+3+k+n8];
}
for (i=0,j=1;j<m;j++)
{
// b = location of point[i,j] in dat[]
b=((n*j)+i)*8;
// copy
for (k=0;k<3;k++) dat[b+3+k]=dat[b+3+k+8];
}
// old api render (just for debug ignore this)
glBegin(GL_TRIANGLES);
for (i=0;i<sz1;i++)
{
j=idx[i];
glNormal3fv(dat+j+3);
glTexCoord3fv(dat+j+6);
glVertex3fv(dat+j);
}
glEnd();
}
Just beware that the normals are single sided so your lighting equation shoul dhandle that otherwise one side would be dark with lighting.
The normals are averaged between 2 triangles in each grid cell (if you want more smooth surface average 4 triangles).
Here preview:
If I did not make any silly mistake somewhere the data format should match yours ... So just remove the old api rendering and add the VBO stuff instead of it

openGL - orthogonal projection matrix

I'm very new to openGL and I am doing a mini project where I experiment with the depth buffer. I got to the stage of displaying it to the screen. However I want to draw it as screen coordinates instead of converting to floats. I read somewhere that I need to use a projection matrix. I have looked for ages and tested loads of different options but I can't seem to get it right.
Can anyone point me to a useful resource or explain how I would go about doing this?
EDIT
At the moment my matrix looks like this:
projectionMat = glm::ortho(0.0f, (float)_cols, 0.0f, (float)_rows, 0.0f, (float)_maxDepthVal);
projection = glGetUniformLocation(_program, "Projection");
glUniformMatrix4fv(projection, 1, GL_FALSE, glm::value_ptr(projectionMat));
EDIT 2
With some fiddling I found that cols had to be negative for some strange reason before it would display. I twill now display correctly on the screen but for some reason it his a gap around the sides opposite the origin, why is this? Even a small move in the camera position and target cause all of it to vanish so I don't think that would be the problem.
Pixel Art Representation!!
OOOO!!
OOOO!!
OOOO!!
!!!!!!!!!!!!!!
New code
glm::mat4 Projection = glm::ortho(0.0f, -static_cast<float>(_cols), 0.0f, static_cast<float>(_rows), 0.0f, static_cast<float>(_maxDepthVal));
projection = glGetUniformLocation(_program, "Projection");
glm::mat4 View = glm::lookAt(
glm::vec3(0.0f, 0.0f, -0.1f),
glm::vec3(0.0f , 0.0f, 0.0f), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model = glm::mat4(1.0f);
projectionMat = Projection * View * Model;
glUniformMatrix4fv(projection, 1, GL_FALSE, glm::value_ptr(projectionMat));
EDIT 3
I can translate it using the Model matrix but it has a gap of 5 pixels around it that I can't get rid of, any help on that would be appreciated but thanks for taken an interest.
UPDATE
As per request my draw code
glUseProgram(_program);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
SDL_GL_SwapWindow(_window);
glPointSize(1);
glEnableVertexAttribArray(0);
//Insert matrix here
glVertexAttribPointer(0, 3, GL_UNSIGNED_INT, GL_FALSE, 0, 0);
glDrawArrays(GL_POINTS, 0, _dataCount)
glDisableVertexAttribArray(0);
my vbo:
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, _dataCount * 4 * sizeof(unsigned int), NULL, GL_STATIC_DRAW);
if(_vbo == 0 || glGetError() != GL_NO_ERROR)
{
_errorMessage = "VBO COULD NOT BE CREATED";
error();
}
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&vbo, _vbo, cudaGraphicsMapFlagsNone));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
I'm also having issues with the write as when it converts to floats(for drawing) it loses precision so if I read the value out again it rounds to the nearest factor(0, 256, 512 etc.). Is there another way to do it that stores it as unsigned int. (I realize this is getting slightly off topic but any help would be appreciated)
The issue appeared to be with the cols variable, it needed to be inverted to work otherwise it was off the screen.