[英]OpenGL Batch Rendering with indices [duplicate]
我正在尝试使用批处理渲染系统一次渲染多个纹理。 但是我遇到了索引问题。 我在 Windows 上使用 OpenGL 4.6。 我创建了一个较小的程序来复制我的原始程序而不添加纹理,以查看四边形是否可以正确渲染。 使用下面的代码,我得到了这个(只有两个四边形渲染):
但是当我将第三个四边形的索引从“2.0f”更改为“1.0f”时,如下所示:
864.0f, 392.0f, 0.0f, 1.0f, 1.0f,
928.0f, 392.0f, 1.0f, 1.0f, 1.0f,
864.0f, 458.0f, 0.0f, 0.0f, 1.0f,
928.0f, 458.0f, 1.0f, 0.0f, 1.0f
我对这一切还是陌生的,所以我很感激任何建议/帮助。
主.cpp:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "Shader.h"
#include <iostream>
using namespace std;
int main() {
// Initialise GLFW
if (!glfwInit()) {
cerr << "Failed to initialize GLFW" << endl;
return 0;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window {glfwCreateWindow(1280, 720, "2D GAME", NULL, NULL)};
if (window == NULL) {
cerr << "Failed to open GLFW window." << endl;
glfwTerminate();
return 0;
}
glfwMakeContextCurrent(window);
glewExperimental = true;
if (glewInit() != GLEW_OK) { // Initialize Glew
cerr << "Failed to initialize GLEW" << endl;
glfwTerminate();
return 0;
}
// Settings
cout << "OpenGL Version: " << glGetString(GL_VERSION) << endl;
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
//Vertex Array
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
// Vertex Buffers
GLuint VBOs[2];
glGenBuffers(2, VBOs);
GLfloat vbData[60] {
// X Y U V Index
512.0f, 392.0f, 0.0f, 1.0f, 0.0f,
576.0f, 392.0f, 1.0f, 1.0f, 0.0f,
512.0f, 458.0f, 0.0f, 0.0f, 0.0f,
576.0f, 458.0f, 1.0f, 0.0f, 0.0f,
736.0f, 392.0f, 0.0f, 1.0f, 1.0f,
800.0f, 392.0f, 1.0f, 1.0f, 1.0f,
736.0f, 458.0f, 0.0f, 0.0f, 1.0f,
800.0f, 458.0f, 1.0f, 0.0f, 1.0f,
864.0f, 392.0f, 0.0f, 1.0f, 1.0f,
928.0f, 392.0f, 1.0f, 1.0f, 1.0f,
864.0f, 458.0f, 0.0f, 0.0f, 1.0f,
928.0f, 458.0f, 1.0f, 0.0f, 1.0f
};
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glBufferData(GL_ARRAY_BUFFER, 60 * sizeof(GLfloat), vbData, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); // Position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr);
glEnableVertexAttribArray(1); // Texture Coords
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat)));
glEnableVertexAttribArray(2); // Texture Index
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBOs[1]);
GLuint ibData[18] {
0, 1, 2, 1, 2, 3,
4, 5, 6, 5, 6, 7,
8, 9, 10, 9, 10, 11
};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 18 * sizeof(GLuint), ibData, GL_STATIC_DRAW);
// MVP
glm::mat4 Projection {glm::ortho(0.0f, 1280.0f, 0.0f, 720.0f, 0.0f, 1.0f)};
glm::mat4 View {glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0))};
glm::vec3 translationA {glm::vec3(0, 0, 0)};
glm::mat4 Model = glm::translate(glm::mat4(1.0f), translationA); // Model Matrix (Using Identity Matrix - Origin)
glm::mat4 mvp = Projection * View * Model; // ModelViewProjection Matrix (MVP) *Matrix multiplication is the other way around*
// Shader
Shader shader {"shader/vertex.vert", "shader/fragment.frag"};
shader.bind();
shader.setUniformMat4f("MVP", mvp);
int sampler[] {0, 1, 2};
shader.setUniform1iv("v_Textures", sampler, 3);
// MAIN LOOP //
while (glfwWindowShouldClose(window) == 0) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, nullptr);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
}
着色器.cpp:
#include <GL/glew.h>
#include "Shader.h"
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
Shader::Shader(const std::string &vertFilePath, const std::string &fragFilePath)
: vertFilePath{vertFilePath}, fragFilePath{fragFilePath}, ID{0} {
ID = LoadShaders(vertFilePath, fragFilePath); // Create & Compile program from shaders
}
Shader::~Shader() {
glDeleteProgram(ID);
}
unsigned int Shader::compileShader(const unsigned int type, const string &filePath) {
unsigned int shaderID {glCreateShader(type)};
std::string shaderCode;
std::ifstream shaderStream(filePath);
// Check if file is valid
if (shaderStream.is_open()) {
std::stringstream sstr;
sstr << shaderStream.rdbuf();
shaderCode = sstr.str();
shaderStream.close();
} else {
cout << "Failed to open shader file: " << filePath << endl;
glDeleteShader(shaderID);
return 0;
}
const char *src = shaderCode.c_str();
// Compile Shader
cout << "Compiling shader: " << filePath << endl;
glShaderSource(shaderID, 1, &src, nullptr);
glCompileShader(shaderID);
// Check Shader
int result;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE) {
int infoLogLength;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
char *shaderErrorMessage {(char *) alloca(infoLogLength * sizeof(char))};
glGetShaderInfoLog(shaderID, infoLogLength, &infoLogLength, shaderErrorMessage);
cout << "Failed to compile shader: " << filePath << '\n' << shaderErrorMessage << endl;
glDeleteShader(shaderID);
return 0;
}
return shaderID;
}
unsigned int Shader::LoadShaders(const string &vertexFilePath, const string &fragmentFilePath) {
// Create the shaders
unsigned int vertexShader {compileShader(GL_VERTEX_SHADER, vertexFilePath)};
unsigned int fragmentShader {compileShader(GL_FRAGMENT_SHADER, fragmentFilePath)};
// Link the program
unsigned int programID = glCreateProgram();
glAttachShader(programID, vertexShader);
glAttachShader(programID, fragmentShader);
glLinkProgram(programID);
glValidateProgram(programID);
cout << "Program Linked!" << endl;
// Detach and Delete Shaders
glDetachShader(programID, vertexShader);
glDetachShader(programID, fragmentShader);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// Check program
int result;
glGetProgramiv(programID, GL_LINK_STATUS, &result);
if (result == GL_FALSE) {
int infoLogLength;
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
char *programErrorMessage {(char *) alloca(infoLogLength * sizeof(char))};
glGetProgramInfoLog(programID, infoLogLength, &infoLogLength, programErrorMessage);
cout << "Failed to compile program\n" << programErrorMessage << endl;
glDeleteProgram(programID);
return 0;
}
return programID;
}
void Shader::bind() const {
glUseProgram(ID);
}
void Shader::unbind() const {
glUseProgram(0);
}
void Shader::setUniform1iv(const std::string &name, const int *array, int size) const {
glUniform1iv(getUniformLocation(name), size, array);
}
void Shader::setUniformMat4f(const std::string &name, const glm::mat4 &matrix) const {
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &matrix[0][0]);
}
unsigned int Shader::getUniformLocation(const std::string &name) const {
if (uniformLocationCache.find(name) != uniformLocationCache.end())
return uniformLocationCache[name];
int location {glGetUniformLocation(ID, name.c_str())};
if (location == -1)
std::cout << "Warning: uniform " << name << " doesn't exist!" << std::endl;
uniformLocationCache[name] = location;
return location;
}
顶点着色器:
#version 460 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in float texIndex;
out vec2 v_TexCoord;
out float v_TexIndex;
uniform mat4 MVP;
void main() {
gl_Position = MVP * vec4(position, 1.0);
v_TexCoord = texCoord;
v_TexIndex = texIndex;
}
片段着色器:
#version 460 core
in vec2 v_TexCoord;
in float v_TexIndex;
uniform sampler2D v_Textures[2];
void main() {
gl_FragColor = texture2D(v_Textures[int(v_TexIndex)], v_TexCoord);
}
我正在尝试使用批处理渲染系统一次渲染多个纹理。 但是我遇到了索引问题。 我在 Windows 上使用 OpenGL 4.6。 我创建了一个较小的程序来复制我的原始程序而不添加纹理,以查看四边形是否可以正确渲染。 使用下面的代码,我得到了这个(只有两个四边形渲染):
但是当我将第三个四边形的索引从“2.0f”更改为“1.0f”时,如下所示:
864.0f, 392.0f, 0.0f, 1.0f, 1.0f,
928.0f, 392.0f, 1.0f, 1.0f, 1.0f,
864.0f, 458.0f, 0.0f, 0.0f, 1.0f,
928.0f, 458.0f, 1.0f, 0.0f, 1.0f
我对这一切还是陌生的,所以我很感激任何建议/帮助。
主.cpp:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "Shader.h"
#include <iostream>
using namespace std;
int main() {
// Initialise GLFW
if (!glfwInit()) {
cerr << "Failed to initialize GLFW" << endl;
return 0;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window {glfwCreateWindow(1280, 720, "2D GAME", NULL, NULL)};
if (window == NULL) {
cerr << "Failed to open GLFW window." << endl;
glfwTerminate();
return 0;
}
glfwMakeContextCurrent(window);
glewExperimental = true;
if (glewInit() != GLEW_OK) { // Initialize Glew
cerr << "Failed to initialize GLEW" << endl;
glfwTerminate();
return 0;
}
// Settings
cout << "OpenGL Version: " << glGetString(GL_VERSION) << endl;
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
//Vertex Array
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
// Vertex Buffers
GLuint VBOs[2];
glGenBuffers(2, VBOs);
GLfloat vbData[60] {
// X Y U V Index
512.0f, 392.0f, 0.0f, 1.0f, 0.0f,
576.0f, 392.0f, 1.0f, 1.0f, 0.0f,
512.0f, 458.0f, 0.0f, 0.0f, 0.0f,
576.0f, 458.0f, 1.0f, 0.0f, 0.0f,
736.0f, 392.0f, 0.0f, 1.0f, 1.0f,
800.0f, 392.0f, 1.0f, 1.0f, 1.0f,
736.0f, 458.0f, 0.0f, 0.0f, 1.0f,
800.0f, 458.0f, 1.0f, 0.0f, 1.0f,
864.0f, 392.0f, 0.0f, 1.0f, 1.0f,
928.0f, 392.0f, 1.0f, 1.0f, 1.0f,
864.0f, 458.0f, 0.0f, 0.0f, 1.0f,
928.0f, 458.0f, 1.0f, 0.0f, 1.0f
};
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glBufferData(GL_ARRAY_BUFFER, 60 * sizeof(GLfloat), vbData, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); // Position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr);
glEnableVertexAttribArray(1); // Texture Coords
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *) (2 * sizeof(GLfloat)));
glEnableVertexAttribArray(2); // Texture Index
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *) (4 * sizeof(GLfloat)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBOs[1]);
GLuint ibData[18] {
0, 1, 2, 1, 2, 3,
4, 5, 6, 5, 6, 7,
8, 9, 10, 9, 10, 11
};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 18 * sizeof(GLuint), ibData, GL_STATIC_DRAW);
// MVP
glm::mat4 Projection {glm::ortho(0.0f, 1280.0f, 0.0f, 720.0f, 0.0f, 1.0f)};
glm::mat4 View {glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0))};
glm::vec3 translationA {glm::vec3(0, 0, 0)};
glm::mat4 Model = glm::translate(glm::mat4(1.0f), translationA); // Model Matrix (Using Identity Matrix - Origin)
glm::mat4 mvp = Projection * View * Model; // ModelViewProjection Matrix (MVP) *Matrix multiplication is the other way around*
// Shader
Shader shader {"shader/vertex.vert", "shader/fragment.frag"};
shader.bind();
shader.setUniformMat4f("MVP", mvp);
int sampler[] {0, 1, 2};
shader.setUniform1iv("v_Textures", sampler, 3);
// MAIN LOOP //
while (glfwWindowShouldClose(window) == 0) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, nullptr);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
}
着色器.cpp:
#include <GL/glew.h>
#include "Shader.h"
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
Shader::Shader(const std::string &vertFilePath, const std::string &fragFilePath)
: vertFilePath{vertFilePath}, fragFilePath{fragFilePath}, ID{0} {
ID = LoadShaders(vertFilePath, fragFilePath); // Create & Compile program from shaders
}
Shader::~Shader() {
glDeleteProgram(ID);
}
unsigned int Shader::compileShader(const unsigned int type, const string &filePath) {
unsigned int shaderID {glCreateShader(type)};
std::string shaderCode;
std::ifstream shaderStream(filePath);
// Check if file is valid
if (shaderStream.is_open()) {
std::stringstream sstr;
sstr << shaderStream.rdbuf();
shaderCode = sstr.str();
shaderStream.close();
} else {
cout << "Failed to open shader file: " << filePath << endl;
glDeleteShader(shaderID);
return 0;
}
const char *src = shaderCode.c_str();
// Compile Shader
cout << "Compiling shader: " << filePath << endl;
glShaderSource(shaderID, 1, &src, nullptr);
glCompileShader(shaderID);
// Check Shader
int result;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE) {
int infoLogLength;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
char *shaderErrorMessage {(char *) alloca(infoLogLength * sizeof(char))};
glGetShaderInfoLog(shaderID, infoLogLength, &infoLogLength, shaderErrorMessage);
cout << "Failed to compile shader: " << filePath << '\n' << shaderErrorMessage << endl;
glDeleteShader(shaderID);
return 0;
}
return shaderID;
}
unsigned int Shader::LoadShaders(const string &vertexFilePath, const string &fragmentFilePath) {
// Create the shaders
unsigned int vertexShader {compileShader(GL_VERTEX_SHADER, vertexFilePath)};
unsigned int fragmentShader {compileShader(GL_FRAGMENT_SHADER, fragmentFilePath)};
// Link the program
unsigned int programID = glCreateProgram();
glAttachShader(programID, vertexShader);
glAttachShader(programID, fragmentShader);
glLinkProgram(programID);
glValidateProgram(programID);
cout << "Program Linked!" << endl;
// Detach and Delete Shaders
glDetachShader(programID, vertexShader);
glDetachShader(programID, fragmentShader);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// Check program
int result;
glGetProgramiv(programID, GL_LINK_STATUS, &result);
if (result == GL_FALSE) {
int infoLogLength;
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
char *programErrorMessage {(char *) alloca(infoLogLength * sizeof(char))};
glGetProgramInfoLog(programID, infoLogLength, &infoLogLength, programErrorMessage);
cout << "Failed to compile program\n" << programErrorMessage << endl;
glDeleteProgram(programID);
return 0;
}
return programID;
}
void Shader::bind() const {
glUseProgram(ID);
}
void Shader::unbind() const {
glUseProgram(0);
}
void Shader::setUniform1iv(const std::string &name, const int *array, int size) const {
glUniform1iv(getUniformLocation(name), size, array);
}
void Shader::setUniformMat4f(const std::string &name, const glm::mat4 &matrix) const {
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &matrix[0][0]);
}
unsigned int Shader::getUniformLocation(const std::string &name) const {
if (uniformLocationCache.find(name) != uniformLocationCache.end())
return uniformLocationCache[name];
int location {glGetUniformLocation(ID, name.c_str())};
if (location == -1)
std::cout << "Warning: uniform " << name << " doesn't exist!" << std::endl;
uniformLocationCache[name] = location;
return location;
}
顶点着色器:
#version 460 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in float texIndex;
out vec2 v_TexCoord;
out float v_TexIndex;
uniform mat4 MVP;
void main() {
gl_Position = MVP * vec4(position, 1.0);
v_TexCoord = texCoord;
v_TexIndex = texIndex;
}
片段着色器:
#version 460 core
in vec2 v_TexCoord;
in float v_TexIndex;
uniform sampler2D v_Textures[2];
void main() {
gl_FragColor = texture2D(v_Textures[int(v_TexIndex)], v_TexCoord);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.