我目前正在准备一切写我自己的游戏在c使用GLFW。我以前从来没有用C写过游戏,只在C#中使用Unity。我对GLSL完全陌生。我发现了如何渲染文本,一切工作基本上都很好,但现在我有一个问题(我认为)投影矩阵。我使用GLFWmonitor来获取屏幕分辨率,并在此分辨率下运行窗口:
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
std::cout << "Monitor resolution: " << mode->width << "x" << mode->height << std::endl;
CBWindow window(mode->width, mode->height, "City Builder");
字符集
从我得到的cout:
Monitor resolution: 1440x900
型
然后我从文本渲染器开始,使用glfwGetWindowSize
来获取窗口大小,并将投影矩阵设置为这个大小,但出现了一些问题。就好像我可以呈现文本的空间只在我的窗口的一小部分中可用:
的数据
出于调试原因,我开始打印从glfwGetWindowSize
得到的宽度和高度,我看到这不是100%,但它应该可以工作:
Window size: 1440x793
型
我不知道为什么我得到这个不正确的数字,我不知道为什么我不能在整个屏幕上渲染。
下面是负责渲染文本的函数:
void TextRenderer::renderText(GLFWwindow *window, const std::string& text, GLfloat x, GLfloat y, GLfloat scale, const glm::vec3& color) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
this->shader.use();
int w, h;
glfwGetWindowSize(window, &w, &h);
std::cout << "Window size: " << w << "x" << h << std::endl;
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(w), 0.0f, static_cast<GLfloat>(h));
this->shader.setUniform("textColor", color);
this->shader.setUniform("projection", projection);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(this->VAO);
// iterate through all characters
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++) {
Character ch = this->font.getCharacters().at(*c);
GLfloat xpos = x + ch.Bearing.x * scale;
GLfloat ypos = y - (ch.Size.y - ch.Bearing.y) * scale;
GLfloat w = ch.Size.x * scale;
GLfloat h = ch.Size.y * scale;
// update VBO for each character
GLfloat vertices[6][4] = {
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos, ypos, 0.0, 1.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos + w, ypos + h, 1.0, 0.0 }
};
// render glyph texture over quad
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
// update content of VBO memory
glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// render quad
glDrawArrays(GL_TRIANGLES, 0, 6);
x += (ch.Advance >> 6) * scale;
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
this->shader.unuse();
glDisable(GL_BLEND);
}
型
片段着色器:
#version 330 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D text;
uniform vec3 textColor;
void main()
{
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
color = vec4(textColor, 1.0) * sampled;
}
型
和顶点着色器:
#version 330 core
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>
out vec2 TexCoords;
uniform mat4 projection;
void main()
{
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
TexCoords = vertex.zw;
}
型
我们在renderText方法中使用的着色器函数只使用glUseProgram
和设置uniform的函数。
下面是我如何使用这些函数:
#include <iostream>
#include <glm/ext/matrix_clip_space.hpp>
#include "Display/Window.h"
#include "Renderer/Shader.h"
#include "vendor/stb/stb_truetype.h"
#include "Renderer/UI/Text/Font.h"
#include "Renderer/UI/Text/TextRenderer.h"
int main() {
if(!glfwInit()){
printf("Failed to initialize OpenGL\n");
exit(1);
}
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
std::cout << "Monitor resolution: " << mode->width << "x" << mode->height << std::endl;
CBWindow window(mode->width, mode->height, "City Builder");
Shader shader("../assets/shaders/Text/vert.glsl", "../assets/shaders/Text/frag.glsl");
Font font("../assets/fonts/Arial.ttf", 48);
TextRenderer textRenderer(shader, font);
double lastTime = glfwGetTime();
int nbFrames = 0;
std::string fps_text;
while(!glfwWindowShouldClose(window.GetWindow())){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
double currentTime = glfwGetTime();
nbFrames++;
if ( currentTime - lastTime >= 1.0 ){
fps_text = "FPS: " + std::to_string(nbFrames);
nbFrames = 0;
lastTime += 1.0;
}
textRenderer.renderText(window.GetWindow(),fps_text, 1400, 0, 1, glm::vec3(1.0f, 0.0f, 0.0f));
textRenderer.renderText(window.GetWindow(),fps_text, 0, 790, 1, glm::vec3(1.0f, 0.0f, 0.0f));
glfwSwapBuffers(window.GetWindow());
glfwPollEvents();
}
glfwTerminate();
return 0;
}
型
谢谢你的时间
1条答案
按热度按时间wztqucjr1#
是否有可能丢失的107个像素被窗口标题栏使用?这是有意义的,因为你不能在标题栏上呈现文本。但这只是一个假设。
显示器大小与窗口大小不同。
如果我的假设是正确的,你应该尝试将窗口设置为全屏模式。我希望这对你有帮助:)