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

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

Related

Align a matrix to a vector in OpenGL

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());

Drawing 2D text over 3D scene with OpenGLES2?

I'm trying to render 2D text over a 3D scene. The 2D text is loaded using freetype from a TTF font and uses an orthographic projection to render and the scene uses a perspective projection using my camera. I have modified the code from this Learn OpenGL tutorial for text rendering. I can render the text by itself and the 3D scene separately however the 2D text does not appear when drawing them together.
My render function:
void Engine::render()
{
std::string fpsStr = std::to_string(fps).substr(0, std::to_string(fps).find(".") + 3);
glViewport(0, 0, surface_width, surface_height);
glClearColor(0.53f, 0.8f, 0.92f, 1.0f);
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 3D scene gets rendered here
scene->render(display, surface, deltaTime);
//
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Text gets rendered here
debugText.renderText(fpsStr,25.0f, 25.0f, 1.0f, glm::vec3(0.0, 0.0, 0.0));
//
glDisable(GL_BLEND);
eglSwapBuffers(display, surface);
}
The text projection is a member variable (glm::mat4) that is initialized during creation of the text rendering class like so:
...
projection = glm::ortho(0.0f, static_cast<float>(screenWidth), 0.0f, static_cast<float>(screenHeight));
...
My render text function:
void Font::renderText(std::string text, float x, float y, float scale, glm::vec3 colour)
{
// activate corresponding render state
textShader.use();
textShader.setMat4("projection", projection);
textShader.setVec3("textColor", colour);
glActiveTexture(GL_TEXTURE0);
// iterate through all characters
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++)
{
Character ch = characters[*c];
float xpos = x + ch.bearing.x * scale;
float ypos = y - (ch.size.y - ch.bearing.y) * scale;
float w = ch.size.x * scale;
float h = ch.size.y * scale;
// update VBO for each character
float vertices[6][4] = {
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos, ypos, 0.0f, 1.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos + w, ypos + h, 1.0f, 0.0f }
};
// render glyph texture over quad
glBindTexture(GL_TEXTURE_2D, ch.textureID);
// update content of VBO memory
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// render quad
glDrawArrays(GL_TRIANGLES, 0, 6);
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
x += (ch.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64)
}
glBindTexture(GL_TEXTURE_2D, 0);
}
Here are two images, in this one I'm only rendering the text and in this one I've enabled both the 3D scene and the text, however only the 3D scene is displayed.
How can I overlay this 2D perspective over the 3D scene so they both get rendered?
You have said that rendering them (the 2D quad and 3D scene) separately works fine but rendering them together works causes the 2D quad not to render. Hmmm, try checking your rendering order of the objects; make sure you are binding and unbinding your shaders correctly.
Is there a particular reason you have disabled depth testing for the text (try enabling it and see if that fixes the problem) ?

OpenGL Problems with Rendering Multiple Objects

I'm brand new to OpenGL and am having some difficulty rendering multiple objects.
I have a vector each of which has its own VertexBuffer. Then, in the while loop I draw each shape on its own.
It's all well and good when I have many of the same objects (multiple cubes etc.) however, when I add a triangle mesh everything gets all out of whack.
I can have many cubes
I can have a single triangle mesh:
But, when I try to have a cube and then a triangle mesh I get:
I'm totally at a loss for what's going on. The code for my loop is provided below.
while (!glfwWindowShouldClose(window))
{
// Get the size of the window
int width, height;
glfwGetWindowSize(window, &width, &height);
float aspect_ratio = 1 * float(height)/float(width); // corresponds to the necessary width scaling
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
// Clear the framebuffer
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Enable depth test
glEnable(GL_DEPTH_TEST);
glUniform3f(program.uniform("triangleColor"), 1.0f, 1.0f, 1.0f);
glUniformMatrix4fv(program.uniform("proj"), 1, GL_FALSE, projection.data());
glUniformMatrix4fv(program.uniform("view"), 1, GL_FALSE, view.data());
int tally = 0;
for (int i = 0; i < surfaces.size(); i++) {
Surface *s = surfaces[i];
Vector3f color = s->getColor();
int tempIndex = triangleIndex;
Matrix4f model = s->getModel();
// Convert screen position to world coordinates
double xworld = ((xpos/double(width))*2)-1;
double yworld = (((height-1-ypos)/double(height))*2)-1; // NOTE: y axis is flipped in glfw
if (isPressed && mode == "translate") {
if(tempIndex == i) {
Vector4f center = s->getCenter() + model.col(3);
Vector4f displacement = Vector4f(xworld, yworld, 0, 1) - center;
Matrix4f translation = translateMatrix(displacement(0), displacement(1), displacement(2));
model = translation * s->getModel();
s->setModel(model);
}
}
glUniform3f(program.uniform("triangleColor"), color(0), color(1), color(2));
glUniformMatrix4fv(program.uniform("model"), 1, GL_FALSE, model.data());
glDrawArrays(GL_TRIANGLES, 0, s->getVertices().size());
}
And I initialize each VBO when making the object as
VertexBufferObject VBO;
VBO.init();
VBO.update(Vertices);
program.bindVertexAttribArray("position", VBO);
Surface* s = new Surface(VBO, Vertices, percentScale, 0, transformedCenter, SmoothNormals, FlatNormals, color);
s->setModel(model);
surfaces.push_back(s);
And where Program::bindVertexAttribArray is defined as
GLint Program::bindVertexAttribArray(
const std::string &name, VertexBufferObject& VBO) const
{
GLint id = attrib(name);
if (id < 0)
return id;
if (VBO.id == 0)
{
glDisableVertexAttribArray(id);
return id;
}
VBO.bind();
glEnableVertexAttribArray(id);
glVertexAttribPointer(id, VBO.rows, GL_FLOAT, GL_FALSE, 0, 0);
check_gl_error();
return id;
}
You're not binding any buffers before the draw call. You're probably simply drawing whatever buffer you last bound when you initialised them. You'll need something like this at the end of your loop before glDrawArrays:
...
program.bindVertexAttribArray("position", VBO); // where VBO is the buffer of surface s
glUniform3f(program.uniform("triangleColor"), color(0), color(1), color(2));
glUniformMatrix4fv(program.uniform("model"), 1, GL_FALSE, model.data());
glDrawArrays(GL_TRIANGLES, 0, s->getVertices().size());

How to get keyboard navigation in OpenGL

I'm trying to create a solar system in OpenGL. I have the basic code for earth spinning on its axis and im trying to set the camera to move with the arrow keys.
using namespace std;
using namespace glm;
const int windowWidth = 1024;
const int windowHeight = 768;
GLuint VBO;
int NUMVERTS = 0;
bool* keyStates = new bool[256]; //Create an array of boolean values of length 256 (0-255)
float fraction = 0.1f; //Fraction for navigation speed using keys
// Transform uniforms location
GLuint gModelToWorldTransformLoc;
GLuint gWorldToViewToProjectionTransformLoc;
// Lighting uniforms location
GLuint gAmbientLightIntensityLoc;
GLuint gDirectionalLightIntensityLoc;
GLuint gDirectionalLightDirectionLoc;
// Materials uniform location
GLuint gKaLoc;
GLuint gKdLoc;
// TextureSampler uniform location
GLuint gTextureSamplerLoc;
// Texture ID
GLuint gTextureObject[11];
//Navigation variables
float posX;
float posY;
float posZ;
float viewX = 0.0f;
float viewY = 0.0f;
float viewZ = 0.0f;
float dirX;
float dirY;
float dirZ;
vec3 cameraPos = vec3(0.0f,0.0f,5.0f);
vec3 cameraView = vec3(viewX,viewY,viewZ);
vec3 cameraDir = vec3(0.0f,1.0f,0.0f);
These are all my variables that im using to edit the camera.
static void renderSceneCallBack()
{
// Clear the back buffer and the z-buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Create our world space to view space transformation matrix
mat4 worldToViewTransform = lookAt(
cameraPos, // The position of your camera, in world space
cameraView, // where you want to look at, in world space
cameraDir // Camera up direction (set to 0,-1,0 to look upside-down)
);
// Create out projection transform
mat4 projectionTransform = perspective(45.0f, (float)windowWidth / (float)windowHeight, 1.0f, 100.0f);
// Combine the world space to view space transformation matrix and the projection transformation matrix
mat4 worldToViewToProjectionTransform = projectionTransform * worldToViewTransform;
// Update the transforms in the shader program on the GPU
glUniformMatrix4fv(gWorldToViewToProjectionTransformLoc, 1, GL_FALSE, &worldToViewToProjectionTransform[0][0]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(aitVertex), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(aitVertex), (const GLvoid*)12);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(aitVertex), (const GLvoid*)24);
// Set the material properties
glUniform1f(gKaLoc, 0.8f);
glUniform1f(gKdLoc, 0.8f);
// Bind the texture to the texture unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gTextureObject[0]);
// Set our sampler to user Texture Unit 0
glUniform1i(gTextureSamplerLoc, 0);
// Draw triangle
mat4 modelToWorldTransform = mat4(1.0f);
static float angle = 0.0f;
angle+=1.0f;
modelToWorldTransform = rotate(modelToWorldTransform, angle, vec3(0.0f, 1.0f, 0.0f));
glUniformMatrix4fv(gModelToWorldTransformLoc, 1, GL_FALSE, &modelToWorldTransform[0][0]);
glDrawArrays(GL_TRIANGLES, 0, NUMVERTS);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glutSwapBuffers();
}
This is the function that draws the earth onto the screen and determines where the camera is at.
void keyPressed (unsigned char key, int x, int y)
{
keyStates[key] = true; //Set the state of the current key to pressed
cout<<"keyPressed ";
}
void keyUp(unsigned char key, int x, int y)
{
keyStates[key] = false; //Set the state of the current key to released
cout<<"keyUp ";
}
void keyOperations (void)
{
if(keyStates['a'])
{
viewX += 0.5f;
}
cout<<"keyOperations ";
}
These are the functions I'm trying to use to edit the camera variables dynamically
// Create a vertex buffer
createVertexBuffer();
glutKeyboardFunc(keyPressed); //Tell Glut to use the method "keyPressed" for key events
glutKeyboardUpFunc(keyUp); //Tell Glut to use the method "keyUp" for key events
keyOperations();
glutMainLoop();
Finally here's the few lines in my main method where I'm trying to call the key press functions. In the console I see it detects that im pressing them but the planet doesnt move at all, I think I may be calling the keyOperations in the wrong place but I'm not sure.
You are correct, key operations is being called in the wrong place. Where it is now is called once then never again. It needs to go in your update code where you update the rotation of the planet. That way it is called at least once per frame.

glUseProgram affecting more than just the VAO

I have successfully created a VAO which produces a triangle which can then be rotated with the mouse (with help from shaders).
My problem comes when I try to draw something else using the standard 'glBegin()' and 'glEnd()' functions. It draws successfully, but now, when I try to rotate the triangle the new drawing also rotates.
I know the problem is somehow fixed using the glUseProgram() function, but I'm not entirely sure why or where it should be added.
Here is my code (I've added it all but the main area of focus should be the display() and init() functions:
#include <GL/glew/glew.h>
#include <GL/freeglut.h>
#include <CoreStructures\CoreStructures.h>
#include <iostream>
#include "texture_loader.h"
#include "shader_setup.h"
using namespace std;
using namespace CoreStructures;
float theta = 0.0f;
bool mDown = false;
int mouse_x, mouse_y;
GLuint myShaderProgram;
GLuint locT; // location of "T" uniform variable in myShaderProgram
GLuint locR; // location of "R" uniform variable in myShaderProgram
GLuint sunPosVBO, sunColourVBO, sunIndicesVBO, sunVAO;
// Packed vertex arrays for the star object
// 1) Position Array - Store vertices as (x,y) pairs
static GLfloat sunVertices [] = {
-0.1f, 0.7f,
0.1f, 0.7f,
0.0f, 0.55f
};
// 2) Colour Array - Store RGB values as unsigned bytes
static GLubyte sunColors [] = {
255, 0, 0, 255,
255, 255, 0, 255,
0, 255, 0, 255
};
// 4) Index Array - Store indices to star vertices - this determines the order the vertices are to be processed
static GLubyte sunVertexIndices [] = {0, 1, 2};
void setupSunVAO(void) {
glGenVertexArrays(1, &sunVAO);
glBindVertexArray(sunVAO);
// copy star vertex position data to VBO
glGenBuffers(1, &sunPosVBO);
glBindBuffer(GL_ARRAY_BUFFER, sunPosVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(sunVertices), sunVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
// copy star vertex colour data to VBO
glGenBuffers(1, &sunColourVBO);
glBindBuffer(GL_ARRAY_BUFFER, sunColourVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(sunColors), sunColors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (const GLvoid*)0);
// enable position, colour buffer inputs
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// setup star vertex index array
glGenBuffers(1, &sunIndicesVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sunIndicesVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sunVertexIndices), sunVertexIndices, GL_STATIC_DRAW);
glBindVertexArray(0);
}
void report_version(void) {
int majorVersion, minorVersion;
glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
cout << "OpenGL version " << majorVersion << "." << minorVersion << "\n\n";
}
void init(void) {
// initialise glew library
GLenum err = glewInit();
// ensure glew was initialised successfully before proceeding
if (err==GLEW_OK)
cout << "GLEW initialised okay\n";
else
cout << "GLEW could not be initialised\n";
report_version();
glClearColor(0.0, 0.0, 0.0, 0.0);
//
// setup "sun" VBO and VAO object
//
setupSunVAO();
//
// load shader program
//
myShaderProgram = setupShaders(string("Resources\\Shaders\\basic_vertex_shader.txt"), string("Resources\\Shaders\\basic_fragment_shader.txt"));
// get the index / location of the uniform variables "T" and "R" in shader program "myShaderProgram"
locT = glGetUniformLocation(myShaderProgram, "T");
locR = glGetUniformLocation(myShaderProgram, "R");
// "plug-in" shader into GPU pipeline
glUseProgram(myShaderProgram); // we're in the driving seat!!!!! Our shaders now intercept and process our vertices as part of the GPU rendering pipeline (as shown in the lecture notes)
}
// Example rendering functions - draw objects in local, or modelling coordinates
void drawSun(void) {
glBindVertexArray(sunVAO);
glDrawElements(GL_TRIANGLE_STRIP, 3, GL_UNSIGNED_BYTE, (GLvoid*)0);
}
void drawShape()
{
glColor3f(0.0f, 0.6f, 0.2f);
glBegin(GL_POLYGON);
glVertex2f(-1.0f, -1.0f); // Left
glVertex2f(-1.0f, -0.1f);
glVertex2f(-0.9f, -0.05f);
glVertex2f(-0.55f, -0.045f);
glVertex2f(-0.49f, -0.06f);
glVertex2f(-0.4f, -0.055f);
glVertex2f(-0.2f, -0.052f);
glVertex2f(0.0f, -0.02f); // Middle
glVertex2f(0.3f, -0.085f);
glVertex2f(0.5f, -0.08f);
glVertex2f(0.8f, -0.088f);
glVertex2f(1.0f, -0.1f);
glVertex2f(1.0f, -1.0f); // Right
glEnd();
}
//
//
void drawScene()
{
drawSun();
drawShape();
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Setup translation matrix and store in T. Pass this over the the shader with the function glUniformMatrix4fv
GUMatrix4 T = GUMatrix4::translationMatrix(0.01f, 0.01f, 0.0f);
glUniformMatrix4fv(locT, 1, GL_FALSE, (GLfloat*)&T);
// Setup rotation matrix and store in R. Pass this over the the shader with the function glUniformMatrix4fv
GUMatrix4 R = GUMatrix4::rotationMatrix(0.0f, 0.0f, theta);
glUniformMatrix4fv(locR, 1, GL_FALSE, (GLfloat*)&R);
// Draw the scene (the above transformations will be applied to each vertex in the vertex shader)
drawScene();
glutSwapBuffers();
}
void mouseButtonDown(int button_id, int state, int x, int y) {
if (button_id==GLUT_LEFT_BUTTON) {
if (state==GLUT_DOWN) {
mouse_x = x;
mouse_y = y;
mDown = true;
} else if (state == GLUT_UP) {
mDown = false;
}
}
}
void mouseMove(int x, int y) {
if (mDown) {
int dx = x - mouse_x;
int dy = y - mouse_y;
float delta_theta = (float)dy * (3.142f * 0.01f);
theta += delta_theta;
mouse_x = x;
mouse_y = y;
glutPostRedisplay();
}
}
void keyDown(unsigned char key, int x, int y) {
if (key=='r') {
theta = 0.0f;
glutPostRedisplay();
}
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
initCOM();
glutInitContextVersion(3, 3);
glutInitContextProfile (GLUT_COMPATIBILITY_PROFILE);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(800, 800);
glutInitWindowPosition(0, 0);
glutCreateWindow("Combining Transforms");
glutDisplayFunc(display);
glutKeyboardFunc(keyDown);
glutMouseFunc(mouseButtonDown);
glutMotionFunc(mouseMove);
init();
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutMainLoop();
shutdownCOM();
return 0;
}
EDIT
I have an array of x,y vertices and am trying to draw them alongside the above code. For some reason this seems to take vertex data from the sunVAO.
Is there some kind of cache that needs to be cleared? I've searched google and I can't seem to find anyone else who has conflicting VAO and vertex arrays.
(Also, I have checked my code and the vertex data supplied in the array of vertices is correct, they're just not displayed correctly.)
Code:
static GLfloat bottomMarkerVertices[] = {
-0.045f, -0.75f,
0.045f, -0.75f,
-0.07f, -1.0f,
0.07f, -1.0f
};
glVertexPointer(2, GL_FLOAT, 0, bottomMarkerVertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
note: vertex arrays have been enabled.
Assuming you're defining your coordinates in normalized device space (suggested by the apparent absence of a projection matrix), the rendering loop needs to look a little like this:
void drawScene()
{
//update shader parameters for the sun shader if necessary
drawSun();
glUseProgram(0);
// at this point, the PROJECTION and MODELVIEW matrices are both the identity
// so the shape is expected to be in NDCs and is not to be transformed
// at all
drawShape();
glUseProgram(progForSun);
}
Note that I don't advise to mix legacy and modern OpenGL like that. The results of vertex processing triggered by drawShape() are only defined because you're using a compatibility profile context.
The two elements of your scene move together because they are both using the same transformation matrices, specificed by these lines:
// Setup translation matrix and store in T. Pass this over the the shader with the function glUniformMatrix4fv
GUMatrix4 T = GUMatrix4::translationMatrix(0.01f, 0.01f, 0.0f);
glUniformMatrix4fv(locT, 1, GL_FALSE, (GLfloat*)&T);
// Setup rotation matrix and store in R. Pass this over the the shader with the function glUniformMatrix4fv
GUMatrix4 R = GUMatrix4::rotationMatrix(0.0f, 0.0f, theta);
glUniformMatrix4fv(locR, 1, GL_FALSE, (GLfloat*)&R);
If you want drawShape() not to move with the mouse, you need to reset locR with a fixed theta value before you call it.
drawSun();
GUMatrix4 R = GUMatrix4::rotationMatrix(0.0f, 0.0f, 0.0f);
glUniformMatrix4fv(locR, 1, GL_FALSE, (GLfloat*)&R);
drawShape();