I have been experimenting with modern OpenGL and I am trying to make draw functions to automate drawing basic shapes I have done quads successfully but I can't get circles to work my code is good because when you change the drawing mode to GL_POINTS you will see the right pattern it just doesn't work with other modes I'm suspicious of me using the default OpenGL coordinates but I'm not sure
here is my code
#include <GL\glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <Windows.h>
#include <string>
#include <array>
#include "Logging.h"
#include "VertexBuffer.h"
#include "VertexArray.h"
#include "Index Buffer.h"
using namespace std;
// define width and height of our window
int width = 600;
int height = 600;
//define pi
const double pi = 3.14159265359;
const double phi = (1 + sqrt(5) / 2);
// class for creating Shaders
class Shader
{
string vertex_source;
string fragment_source;
unsigned int shader;
int color_location;
unsigned int CompileShader(unsigned int type, string& source)
{
unsigned int id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
//error handling
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
char* message = (char*)_malloca(length * sizeof(char));
glGetShaderInfoLog(id, length, &length, message);
error(message);
glDeleteShader(id);
return 0;
}
return id;
}
unsigned int CreateShader(string& vertexShader, string& fragmentShader)
{
unsigned int Program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(Program, vs);
glAttachShader(Program, fs);
glLinkProgram(Program);
glValidateProgram(Program);
glDeleteShader(vs);
glDeleteShader(fs);
return Program;
}
public:
Shader(const string& file_path)
{
enum class ShadeType
{
NONE = -1, VERTEX = 0, FRAGMENT = 1
};
ifstream stream(file_path);
string line;
stringstream ss[2];
ShadeType type = ShadeType::NONE;
while (getline(stream, line))
{
if (line.find("#shader") != string::npos)
{
if (line.find("vertex") != string::npos)
{
type = ShadeType::VERTEX;
}
else if (line.find("fragment") != string::npos)
{
type = ShadeType::FRAGMENT;
}
}
else
{
ss[(int)type] << line << "\n";
}
}
vertex_source = ss[0].str();
fragment_source = ss[1].str();
shader = CreateShader(vertex_source, fragment_source);
}
void useShader()
{
glUseProgram(shader);
}
void setColor(float red, float green, float blue, float alpha)
{
int color_location = glGetUniformLocation(shader, "u_Color");
glUniform4f(color_location, red, green, blue, alpha);
}
void deleteShader()
{
glDeleteProgram(shader);
}
};
void rectangle(Shader shader, VertexArray vertexArray, double x, double y, double width, double height, array <float, 4> color)
{
//creating a vertex buffer object
VertexBuffer VBuff;
//creating a vertex array
float vertices[] = {
x + width / 2, y + height / 2,
x + width / 2, y - height / 2,
x - width / 2, y - height / 2,
x - width / 2, y + height / 2
};
//writing a vertex array to our vertex buffer
VBuff.write(vertices, sizeof(vertices));
shader.setColor(color[0], color[1], color[2], color[3]);
// bind buffers, ...
VBuff.bind();
vertexArray.bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
// draw
glDrawArrays(GL_POLYGON, 0, sizeof(vertices) / 4 / 2);
// unbind buffers, ...
VBuff.unbind();
vertexArray.unbind();
}
void ellipse(Shader shader, VertexArray vertexArray, array <float, 4> color)
{
VertexBuffer VBuff;
float vertexes[700];
int i = 0;
double a = 0;
while (a < pi*2)
{
if ((i % 2) == 0){ vertexes[i] = cos(a); }
else { vertexes[i] = sin(a); }
a += 0.01;
i += 1;
}
//writing a vertex array to our vertex buffer
VBuff.write(vertexes, sizeof(vertexes));
shader.setColor(color[0], color[1], color[2], color[3]);
// bind buffers, ...
VBuff.bind();
vertexArray.bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
// draw
glDrawArrays(GL_POLYGON, 0, sizeof(vertexes) / 4 / 2);
// unbind buffers, ...
VBuff.unbind();
vertexArray.unbind();
}
// main
int main(void)
{
//making a window object
GLFWwindow* window;
//initialize glfw
if (!glfwInit())
{
error("could not initialize glfw");
return -1;
}
else
{
info("glfw initialized successfully");
}
//setting opengl to opengl 4.0 COMPATIBILITY PROFILE
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
//Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(width, height, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
error("could not create window");
return -1;
}
//Make the window's context current
glfwMakeContextCurrent(window);
// initialize glew
if (glewInit() != GLEW_OK)
{
error("could not initialize glew");
return -1;
}
else
{
info("glew initialized successfully");
}
//creating a shader using the shader file from that path
Shader shader("C:/Users/FMalt/source/repos/C++/res/basic.shader");
//using the before created shader
shader.useShader();
//creating a vertex array object this is for all objects
VertexArray vao;
//code here
//Loop until the user closes the window
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
//render here
ellipse(shader, vao, {1.0, 0.0, 1.0, 1.0});
//end of rendering
// Swap front and back buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
}
info("code ran successfully");
shader.deleteShader();
glfwTerminate();
info("Window closed");
}
info error functions are functions I implemented in other files as well as vertex buffer, index buffer, and vertex array creating
i acually found the problem i made my vertexes list with 700 * 4 bytes of memory (700*float)but i only use 620 so when the program goes above that it draws the vertex in the default value for an uninitialized list