Версии окружности OpenGL для объектов glBufferData()

123
14

У меня возникают трудности с поставкой предварительно рассчитанных вершин для круга, в буферные данные моего консольного приложения. Я получаю сообщение об ошибке, что я не могу преобразовать тип вершин в const void *, но по мере настройки, когда я заменяю свои вершины другими значениями для тестирования, они МОГУТ преобразовать в const void *.

Кто-нибудь может рассказать о моем содержании?

ПЕРВИЧНЫЙ КЛАСС

#include <iostream>
#include <vector>

#include <sstream>
#define GLEW_STATIC
//always GLEW before GLFW
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include "glm/glm.hpp"

#include "ShaderProgram.h"

#ifndef M_PI
# define M_PI 3.141592653
#endif

/////gLOBAL
GLFWwindow* w = NULL;
const int wWidth = 800;
const int wHeight = 600;
const std::vector<glm::vec3> vertices;
const std::vector<unsigned int> indices;
GLfloat Radius = 6;
GLfloat Stacks = 5;
GLfloat Slices = 5;

void key_callback(GLFWwindow *w, int key, int scancode, int action, int mode);
//update colors based on average framerate
void averageFPS(GLFWwindow* window);
//screen resizing
void glfw_onFramebufferSize(GLFWwindow* window, int width, int height);
bool initOpenGL();

static void error(int error, const char *desc)
{
fputs(desc, stderr);
}
//setting up values for keys

int main() {
//pointing to GLFW window
//GLFWwindow *w; //may want to initialize as null outside before main
if (!initOpenGL()) ///5IMPR
{
// An error occured
std::cerr << "GLFW not initialized" << std::endl;
return -1;
}

glfwSetErrorCallback(error);

///BROKEN CIRCLE VERTICES

// Calc The Vertices

for (int i = 0; i <= Stacks; ++i) {

float V = i / (float)Stacks;
float phi = V * M_PI; //change to glm:: pi

// Loop Through Slices
for (int j = 0; j <= Slices; ++j) {

float U = j / (float)Slices;
float theta = U * (M_PI * 2);

// Calc The Vertex Positions
float x = cosf(theta) * sinf(phi);
float y = cosf(phi);
float z = sinf(theta) * sinf(phi);

// Push Back Vertex Data //push_back is a standard vector function which adds a parameter to the end of the vector

vertices.push_back(glm::vec3(x, y, z) * Radius);
}
}

// Calc The Index Positions
for (int i = 0; i < Slices * Stacks + Slices; ++i) {

indices.push_back(i);
indices.push_back(i + Slices + 1);
indices.push_back(i + Slices);

indices.push_back(i + Slices + 1);
indices.push_back(i);
indices.push_back(i + 1);
}

////BROKEN CIRCLE VERTICES END

// 2. Set up buffers on the GPU
GLuint vbo, ibo, vao; ///5IMPROVEdown

glGenBuffers(1, &vbo); // Generate an empty vertex buffer on the GPU
glBindBuffer(GL_ARRAY_BUFFER, vbo); // "bind" or set as the current buffer we are working with
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // copy the data from CPU to GPU

glGenVertexArrays(1, &vao); // Tell OpenGL to create new Vertex Array Object
glBindVertexArray(vao); // Make it the current one
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); // Define a layout for the first vertex buffer "0"
glEnableVertexAttribArray(0); // Enable the first attribute or attribute "0"

// Set up index buffer
glGenBuffers(1, &ibo); // Create buffer space on the GPU for the index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glBindVertexArray(0); // unbind to make sure other code doesn't change it

ShaderProgram shaderProgram; ///5ADD
shaderProgram.assignShaders("shaders/ColorShader.vert", "shaders/ColorShader.frag"); ///5ADD

////////SETUP RENDERING
while (!glfwWindowShouldClose(w))
{
averageFPS(w);

//process events
glfwPollEvents();

// Clear the screen
glClear(GL_COLOR_BUFFER_BIT);

shaderProgram.use(); ///5ADD

GLfloat time = (GLfloat)glfwGetTime(); ///5ADD
GLfloat blueSetting = (sin(time) / 2) + 0.5f; ///5ADD
glm::vec2 pos;
pos.x = sin(time) / 2;
pos.y = cos(time) / 2;
shaderProgram.setUniform("vertColor", glm::vec4(0.0f, 0.0f, blueSetting, 1.0f)); ///5ADD
shaderProgram.setUniform("posOffset", pos);

/////COLOR OF CIRCLE OUTLINE if using draw(LINE_LOOP)
//glColor4f(0.0, 0.0, 1.0, 1.0); //RGBA

glBindVertexArray(vao);

//og for quad
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//glDrawElements(GL_LINE_LOOP, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
// Swap buffers and look for events

glfwSwapBuffers(w);
}
//clean up
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &ibo);

//glfwDestroyWindow(w);
glfwTerminate();

return 0;
}

///////START Initializing glfw glew etc
bool initOpenGL(){

//this method will exit on these conditions
GLuint error = glfwInit();
if (!error)
return false;

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

w = glfwCreateWindow(wWidth, wHeight, "Exercise", NULL, NULL);

//int width, height;
//glfwGetFramebufferSize(w, &width, &height);
/*
// Actual OpenGL calls
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glOrtho(0, width, height, 0, 0, 1);
glOrtho(0.0f, wWidth, wHeight, 0.0f, 0.0f, 1.0f);

glMatrixMode(GL_MODELVIEW);
*/
//Filling Window

if (w== NULL)
{
std::cerr << "glfw window not created" << std::endl;
glfwTerminate();
return false;
}

//update context
glfwMakeContextCurrent(w);

// Initialize GLEWunifor
glewExperimental = GL_TRUE;
GLuint err = glewInit();
if (err != GLEW_OK)
{
std::cerr << "initialize GLEW Failed" << std::endl;
return false;
}

//setup key callbacks
glfwSetKeyCallback(w, key_callback);
glfwSetFramebufferSizeCallback(w, glfw_onFramebufferSize);

glClearColor(0.23f, 0.38f, 0.47f, 1.0f); ///5ADD

// Define the viewport dimensions
glViewport(0, 0, wWidth, wHeight); //necessary?

return true;
}

void key_callback(GLFWwindow *w, int key, int scancode, int action, int mode)
{
// See http://www.glfw.org/docs/latest/group__keys.html
if ((key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) && action == GLFW_PRESS)
glfwSetWindowShouldClose(w, GL_TRUE);

if (key == GLFW_KEY_W && action == GLFW_PRESS)
{
bool showWires = false;
if (showWires)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}

//whever window resizes, do this
void glfw_onFramebufferSize(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}

void averageFPS(GLFWwindow* window) ///5ADDdown
{
static double previousSeconds = 0.0;
static int frameCount = 0;
double passedSeconds;
double currentSeconds = glfwGetTime(); //seconds since GLFW started

passedSeconds = currentSeconds - previousSeconds;

// Limit time updates to 4 times per second
if (passedSeconds > 0.25)
{
previousSeconds = currentSeconds;
double fps = (double)frameCount / passedSeconds;
// double frameInMilSecs = 1000.0 / fps;
frameCount = 0;}
frameCount++;
}

КЛАСС SHADER HANDLER

#include "ShaderProgram.h"
#include <fstream>
#include <iostream>
#include <sstream>

ShaderProgram::ShaderProgram()
: mProgram(0){
}

ShaderProgram::~ShaderProgram()
{
glDeleteProgram(mProgram);
}

bool ShaderProgram::assignShaders(const char* vertFileName, const char* fragFileName)
{
//Shaders output objects called programs that define their relationship and lead to .exe functionality

//assigning pointer to the shader

string vsString = readFile(vertFileName);
string fsString = readFile(fragFileName);

const GLchar* fsSourcePtr = fsString.c_str();
const GLchar* vsSourcePtr = vsString.c_str();

//creating vertex shader(vs) shader object
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);

//assigning shader source using address. Replaces the source code in a shader object //@arg (shader, count Strings, pointer to const File ,size)
glShaderSource(vs, 1, &vsSourcePtr, NULL);
glShaderSource(fs, 1, &fsSourcePtr, NULL);

glCompileShader(vs);
glCompileShader(fs);

testProgramCompile();
testShaderCompile(vs);
testShaderCompile(fs);

//createProgram returns GLUint which is basically an unsigned int... we will use This Handler to create a program object
mProgram = glCreateProgram();
if (mProgram == 0)
{
std::cerr << "Shader cannot be created" << std::endl;
return false;
}
//assign the program object(mProgram) to the Shader
glAttachShader(mProgram, vs);
glAttachShader(mProgram, fs);

//this method accepts a GLuint "program" . If its an object of type GL_VERTEX_SHADER,
//itll create a .exe that runs on the programmable vertex processor. same goes for geometric and fragment shaders if they were included
//it will also bind all user defined uniform variables and attributes to the program
//The program can then be made part of a defined state by calling useProgram
glLinkProgram(mProgram);
testProgramCompile();
testShaderCompile(vs);
testShaderCompile(vs);

//cleaning up the elements we already used
glDeleteShader(vs);
glDeleteShader(fs);

//clear the identifier lookup map(in this case, there only one)
mUniformIdentifiers.clear();

return true;
}//end main

//Read the shaderFile. strngstream for reading multiple lines
string ShaderProgram:: readFile(const string& filename) {

std::stringstream strgstream;
std::ifstream file;

try
{
file.open(filename, std::ios::in);

if (!file.fail())
{
strgstream << file.rdbuf();
}

file.close();
}
catch (std::exception e)
{
std::cerr << "Error: File or File Name Issues" << std::endl;
}

return strgstream.str();
}
//use the Program Object we created in this current state(color)
void ShaderProgram::use()
{
if (mProgram != 0)
glUseProgram(mProgram);
}

void ShaderProgram::testProgramCompile() {
int status = 0;

GLuint program = mProgram;

// ///CHECKING GL_LINK_STATUS to see if Program Link was successul. Link Status will return GL_TRUE if it was
glGetProgramiv( mProgram, GL_LINK_STATUS, &status); //requesting the status
if (status == GL_FALSE)
{

std::cerr << "Linking Error with Program " << std::endl;
}

}

void ShaderProgram :: testShaderCompile(GLuint shader) {
int status = 0;

// ///CHECKING GL_LINK_STATUS to see if Program Link was successul. Link Status will return GL_TRUE if it was
glGetProgramiv(shader, GL_LINK_STATUS, &status); //requesting the status
if (status == GL_FALSE)
{
std::cerr << "Linking Error with Shader " << std::endl;
}
}
////GETTERS AND SETTERS

GLuint ShaderProgram::getProgram() const
{
return mProgram;
}

void ShaderProgram::setUniform(const GLchar* name, const glm::vec2& v)
{
GLint address = getUniformIdentifier(name);
glUniform2f(address, v.x, v.y);
}

void ShaderProgram::setUniform(const GLchar* name, const glm::vec3& v)
{
GLint address = getUniformIdentifier(name);
glUniform3f(address, v.x, v.y, v.z);
}

void ShaderProgram:: setUniform(const GLchar* name, const glm::vec4& v) {
GLint address = getUniformIdentifier(name);
glUniform4f(address, v.x, v.y, v.z, v.w);
}

//Maybe need to switch places with setUniform
GLint ShaderProgram :: getUniformIdentifier(const GLchar* name) {

std::map<std::string, GLint>::iterator it;
it = mUniformIdentifiers.find(name);
//std::map<std::string, GLint>

// Only need to query the shader program IF it doesn't already exist.
if (it == mUniformIdentifiers.end())
{
// Find it and add it to the map
mUniformIdentifiers[name] = glGetUniformLocation(mProgram, name);
}

// Return it
return mUniformIdentifiers[name];
}

спросил(а) 2021-01-19T13:35:52+03:00 2 месяца, 3 недели назад
1
Решение
75

Я получаю сообщение об ошибке, что я не могу преобразовать тип вершин в const void *

Тип vertices и indices объектов определяется как const const. Таким образом, вы не можете писать переменные, вы также не можете вызывать метод объекта, который также не имеет значения const (например, std::vector::push_back).

Поскольку vertices и indices должны содержать вершины и индексы, которые динамически создаются, они не должны быть квалифицированы как const:

std::vector<glm::vec3> vertices;
std::vector<unsigned int> indices;

Конечно, оператор sizeof возвращает размер объекта. Но если оператор sizeof используется для объекта с типом std::vector, то этот размер не является размером содержимого динамических данных, которым управляет объект std::vector. Объект std::vector состоит из указателя на динамические данные, а sizeof возвращает размер указателя.

Указатель на данные, содержащиеся объектом std::vector можно получить по std::vector::data.

Количество элементов, содержащихся в объекте std::vector можно получить по std::vector::size. Размер в байтах должен быть рассчитан по количеству элементов и sizeof одного элемента:

size_t size_in_bytes = vertices.size() * sizeof(*vertices.data()); 


Второй параметр glBufferData должен быть размером в байтах, а третий параметр должен быть указателем на данные:

// note: sizeof(*vertices.data()) == sizeof(glm::vec3)
GLsizeiptr vertices_size = (GLsizeiptr)(vertices.size() * sizeof(*vertices.data()));
glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices.data(), GL_STATIC_DRAW);

// note: sizeof(*indices.data()) == sizeof(unsigned int)
GLsizeiptr indices_size = (GLsizeiptr)(indices.size() * sizeof(*indices.data()));
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_size, indices.data(), GL_STATIC_DRAW);

ответил(а) 2021-01-19T13:35:52+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема