问题描述
我一直在尝试使用现代 OpenGL,我正在尝试使用绘图函数来自动绘制基本形状我已经成功地完成了四边形但我无法让圆圈工作我的代码很好,因为当您将绘图模式更改为 GL_POINTS 时你会看到正确的模式它只是不适用于其他模式我怀疑我使用默认的 OpenGL 坐标,但我不确定
这是我的代码
#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
};
//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,sizeof(vertices) / 4 / 2);
// unbind buffers,...
VBuff.unbind();
vertexArray.unbind();
}
void ellipse(Shader shader,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],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,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 错误函数是我在其他文件中实现的函数 以及顶点缓冲区、索引缓冲区和顶点数组创建
解决方法
使用此代码对我来说效果很好。
我停用了你的 vao,vbo ...
我使用 i
作为大小 (glDrawArrays(GL_POLYGON,i / 2);
)。
检查您的 vao、vbo 和 ibo 实施情况。
#include <GL/glew.h>
#include <GLFW/glfw3.h>
// #include <Windows.h>
#include <array>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
// #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 *)malloc(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};
// 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,vertices);
// draw
glDrawArrays(GL_POLYGON,sizeof(vertices) / 4 / 2);
// unbind buffers,...
// VBuff.unbind();
// vertexArray.unbind();
}
void ellipse(Shader shader,*/ 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],vertexes);
// draw
glDrawArrays(GL_POLYGON,i / 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,1.0f);
// render here
ellipse(shader,{1.0,0.0,1.0,1.0});
// rectangle(shader,0.5,1.0});
// end of rendering
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
shader.deleteShader();
glfwTerminate();
}
,
我最终发现了一个问题,我用 700 * 4 字节的内存(700 * 浮点数)制作了我的顶点列表,但我只使用了 620,所以当程序超过它时,它会在未初始化列表的默认值中绘制顶点