问题描述
我正在尝试在 OpenGL 中渲染一个 2D(屏幕协调)精灵.然而,当我编译它时,它没有出现.我看到代码很好(甚至没有任何着色器编译错误或任何其他错误).我还设置了矩阵(我怀疑这是导致问题的原因,这就是混淆的开始!!)
I am trying to render a 2D(Screen coordinated) sprite in OpenGL. Yet, when I compile it, it does not show up. I see that the code is fine (There are not even any shader compilation errors nor any other errors). I also have also the matrices set up(which I doubt is causing the problem, and that's where starts the CONFUSION!!)
顺便说一下,这里是源代码(没有调试,简短一点):-
Here is the source code, by the way(without debugging, to make it short):-
main.cpp
// Including all required headers here...
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "SOIL2/SOIL2.h"
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
const GLchar * vertexShaderSource =
"#version 330 core
"
"layout(location = 0) in vec4 vertex;
"
"out vec2 TexCoords;
"
"uniform mat4 model;
"
"uniform mat4 projection;
"
"void main()
"
"{
"
"TexCoords = vertex.zw;
"
"gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);
"
"} ";
const GLchar * fragmentShaderSource =
"#version 330 core
"
"in vec2 TexCoords;
"
"out vec4 color;
"
"uniform sampler2D image;
"
"uniform vec3 spriteColor;
"
"void main()
"
"{
"
"color = vec4(spriteColor, 1.0) * texture(image, TexCoords);
"
"} ";
const GLint WIDTH = 800, HEIGHT = 600;
int main()
{
glfwInit();
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, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Rendering Sprites", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
glViewport(0, 0, screenWidth, screenHeight);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GLuint quadVAO;
GLuint VBO;
GLfloat vertices[] =
{
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(quadVAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
GLuint texture;
int width, height;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
unsigned char *image = SOIL_load_image("img.png", &width, &height, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glm::mat4 model;
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(WIDTH), static_cast<GLfloat>(HEIGHT), 0.0f, -1.0f, 1.0f);
glm::vec2 size = glm::vec2(10.0f, 10.0f);
glm::vec2 position = glm::vec2(-10.0f, 10.0f);
glm::vec3 color = glm::vec3(1.0f, 0.0f, 0.0f);
GLfloat rotation = 0.0f;
model = glm::translate(model, glm::vec3(position, 0.0f));
model = glm::translate(model, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f));
model = glm::rotate(model, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::translate(model, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f));
model = glm::scale(model, glm::vec3(size, 1.0f));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniform3f(glGetUniformLocation(shaderProgram, "spriteColor"), color.x, color.y, color.z);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &quadVAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return EXIT_SUCCESS;
}
推荐答案
你必须初始化模型矩阵变量glm::mat4 model
.
You have to initialize the model matrix variable glm::mat4 model
.
glm API 文档 指的是 OpenGL 着色语言规范 4.20.
5.4.2 向量和矩阵构造函数
如果向量构造函数只有一个标量参数,则它用于将构造向量的所有组件初始化为该标量的值.如果矩阵构造函数只有一个标量参数,它用于初始化矩阵对角线上的所有分量,其余分量初始化为 0.0.
If there is a single scalar parameter to a vector constructor, it is used to initialize all components of the constructed vector to that scalar’s value. If there is a single scalar parameter to a matrix constructor, it is used to initialize all the components on the matrix’s diagonal, with the remaining components initialized to 0.0.
这意味着,可以通过单个参数 1.0 来初始化单位矩阵:
This means, that an identity matrix can be initialized by the single parameter 1.0:
glm::mat4 model(1.0f);
此外,您的精灵非常小,并且位于左侧的视口(剪辑空间)之外:
Further your sprite is very small and it is out of the viewport (clip space) at the left side:
像这样改变你的代码:
glm::vec2 position = glm::vec2(10.0f, 10.0f); // 10.0f instead of -10.0f
这篇关于为什么精灵不能在 OpenGL 中渲染?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!