gpt4 book ai didi

c++ - 在 OpenGL 中绘制像素

转载 作者:行者123 更新时间:2023-11-30 02:29:27 25 4
gpt4 key购买 nike

我正在我的大学学习计算机图形学类(class)。我需要在现代 OpenGL(3.3+) 中实现基本的线条绘制算法以在屏幕上绘制基元。这是我要实现的 Bresenham 画线算法的功能 -

void bresenham(GLint xStart, GLint yStart, GLint xEnd, GLint yEnd) {
if (!(xStart < xEnd)) {
swap(xStart, xEnd);
swap(yStart, yEnd);
}

GLint dx = xEnd - xStart;
GLint dy = yEnd - yStart;
GLint p = 2 * dy - dx;

GLint x = xStart;
GLint y = yStart;
setPixel(x,y);

while (x < xEnd) {
x += 1;
if (p < 0)
p += (2 * dy);
else {
p += (2 * (dy - dx));
y += 1;
setPixel(x,y);
}
}
}

我对如何实现setPixel() 函数一无所知。我在这里和其他地方找到的大多数答案都使用旧的 OpenGL 函数 -

void setPixel(int x, int y)
{
glColor3f(0.0, 0.0, 0.0); //Set pixel to black
glBegin(GL_POINTS);
glVertex2i(x, y); //Set pixel coordinates
glEnd();
glFlush(); //Render pixel
}

在 OpenGl 3.3+ 中执行此操作的等效方法是什么?假设我可以将“像素”添加到 std::vector 数组,我该如何初始化顶点缓冲区数组来存储此数据?

我在尝试使用 GL_POINTS 绘制点时遇到的另一个问题是,由于在转换为规范化设备坐标期间发生裁剪,任何方向上超出范围 [-1,1] 的点都不会显示在窗口上。

例如,只有前三个点显示在窗口屏幕上。请参阅 initialize() 函数 -

#include <stdio.h>
#include <stdlib.h>

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cstdlib>
#include <vector>
#include <iostream>
#include <fstream>

// Read a shader source from a file
// store the shader source in a std::vector<char>
void read_shader_src(const char* fname, std::vector<char> &buffer);

// Compile a shader
GLuint load_and_compile_shader(const char *fname, GLenum shaderType);

// Create a program from two shaders
GLuint create_program(const char *path_vert_shader, const char *path_frag_shader);

// Render scene
void display(GLuint &vao, GLFWwindow* window);

// Initialize the data to be rendered
void initialize(GLuint &vao);


//GLFW Callbacks
static void error_callback(int error, const char* description) {
fprintf(stderr, "Error: %s\n", description);
}

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GL_TRUE);
}
}

int main() {
glfwSetErrorCallback(error_callback);
//Initialize GLFW
if (!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW.\n");
return -1;
}

//Set GLFW window settings and create window
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);
GLFWwindow* window = glfwCreateWindow(500, 500, "My window", NULL, NULL);
if(!window) {
fprintf(stderr, "Window or context creation failed.\n");
return -1;
}

glfwSetKeyCallback(window, key_callback);
glfwMakeContextCurrent(window);

//Initialize GLEW
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize glew");
glfwTerminate();
return -1;
}
//Create a vertex array object
GLuint vao;

//Initialize the data to be rendered
initialize(vao);

while (!glfwWindowShouldClose(window)) {
display(vao, window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}

//Render scene
void display(GLuint &vao, GLFWwindow* window) {
//Red background
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);

glBindVertexArray(vao);
glDrawArrays(GL_POINTS, 0, 12);
// Swap front and back buffers
glfwSwapBuffers(window);
}

void initialize(GLuint &vao) {
glEnable(GL_PROGRAM_POINT_SIZE);
// Use a Vertex Array Object
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

//Store verex positions in an array
GLfloat vertices[24] = {
0.0, 0.0, // Only these
0.5, 0.5, //three points show up
1.0, 1.0, //on the window screen

4.0, 4.0,
5.0, 5.0,
6.0, 6.0,

7.0, 7.0,
8.0, 8.0,
9.0, 9.0,

10.0, 10.0,
11.0, 11.0,
12.0, 12.0,
};

//Create a vertex buffer object to store the vertex data
GLuint vbo;
//Generates 1 buffer object name and stores it in vbo
glGenBuffers(1, &vbo);
//Bind the buffer object to the buffer binding target
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//Creates and initializes the buffer object's data store(with data from vertices)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

GLuint shaderProgram = create_program("/Users/.../vert.shader", "/Users/.../frag.shader"); //path to shader files

// Get the location of the attributes that enters in the vertex shader
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");

// Specify how the data for position can be accessed
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

//Enable the attribute
glEnableVertexAttribArray(posAttrib);
}

// Read a shader source from a file
// store the shader source in a std::vector<char>
void read_shader_src(const char *fname, std::vector<char> &buffer) {
std::ifstream in;
in.open(fname, std::ios::binary);

if(in.is_open()) {
// Get the number of bytes stored in this file
in.seekg(0, std::ios::end);
size_t length = (size_t)in.tellg();

// Go to start of the file
in.seekg(0, std::ios::beg);

// Read the content of the file in a buffer
buffer.resize(length + 1);
in.read(&buffer[0], length);
in.close();
// Add a valid C - string end
buffer[length] = '\0';
}
else {
std::cerr << "Unable to open " << fname << " I'm out!" << std::endl;
exit(-1);
}
}

//Compile a shader
GLuint load_and_compile_shader(const char* fname, GLenum shaderType) {
//Load a shader from an external file
std::vector<char> buffer;
read_shader_src(fname, buffer);
const char *src = &buffer[0];

//Create and compile the shader
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);

GLint shader_compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_compiled);
if(!shader_compiled) {
GLchar message[1024];
glGetShaderInfoLog(shader, 1024, NULL, message);
std::cerr << "Shader compilation failed.";
std::cerr << "Log: " << &message << std::endl;
glfwTerminate();
exit(-1);
}
return shader;
}

// Create a program from two shaders
GLuint create_program(const char *path_vert_shader, const char *path_frag_shader) {
// Load and compile the vertex and fragment shaders
GLuint vertexShader = load_and_compile_shader(path_vert_shader, GL_VERTEX_SHADER);
GLuint fragmentShader = load_and_compile_shader(path_frag_shader, GL_FRAGMENT_SHADER);

// Attach the above shader to a program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);

// Flag the shaders for deletion
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

// Link and use the program
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);

return shaderProgram;
}

我要进行哪些修改才能绘制其余的点?

顶点着色器 -

#version 150 core

in vec4 position;

void main() {
gl_Position = position;
gl_PointSize = 10.0;
}

片段着色器 -

#version 150 core

out vec4 out_color;

void main() {
out_color = vec4(1.0, 1.0, 1.0, 1.0);
}

最佳答案

从评论来看,您似乎在尝试使用 OpenGL 代替类所需的非常旧的图形库。由于计算机图形学发生了很大变化,以至于你在现代 OpenGL 中尝试做的事情是不合理的,你应该尝试为当前任务和以后的任务这样做:

免责声明:这不是在现代 OpenGL 中划线的合理方式

  1. 创建一个任意大小的二维数组,大到可以在其上绘制整条线。
  2. 使用原始函数绘制线条,创建一些 setPixel 函数来更改该数组中的元素
  3. 一旦你画完线(或做任何其他你需要做的 future 任务),从该数组创建一个 OpenGL 纹理。此处提供了出色的指南:https://open.gl/textures

一些粗略的伪代码:

GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_FLOAT, pixels);
glBindTexture(GL_TEXTURE_2D, 0);

然后您将创建一个四边形(实际上只是两个三角形)将此纹理绘制到屏幕上。遵循 open.gl 指南应该效果很好,因为他们已经为他们的纹理做了这个。从他们提供的代码中提取(虽然做了一些额外的,但都正确并遵循规范):

GLfloat vertices[] = {
// Position Color Texcoords
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-left
};

GLuint elements[] = {
0, 1, 2,
2, 3, 0
};

// Set up buffer objects, create shaders, initialize GL, etc.

//drawing
//bind buffers, enable attrib arrays, etc
glBindTexture(GL_TEXTURE_2D, tex);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

关于c++ - 在 OpenGL 中绘制像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39430404/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com