- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
前几天我问了一个问题,关于使用 SDL 渲染 TTF 字体,并被指向 SDL_TTFL 我已经尝试使用 SDL_TTF 库,但我得到的只是屏幕上的垃圾
我已经包含了我的着色器,这对于这个程序来说非常简单,还有我用来将文本加载到表面并将其绑定(bind)到纹理的片段。我根本不想在这里做任何疯狂的事情。你能看到我做错了什么吗?我不太确定如何调试着色器等。
#version 330
in vec2 texCoord;
in vec4 fragColor;
out vec3 finalColor;
uniform sampler2D myTextureSampler;
void main() {
finalColor = texture( myTextureSampler, texCoord ).rgb;
}
#version 330
in vec3 vert;
in vec4 color;
in vec2 texcoord;
out vec4 fragColor;
out vec2 texCoord;
void main() {
fragColor = color;
gl_Position = vec4(vert, 1);
texCoord = texcoord;
}
//Initialise TTF
if( TTF_Init() == -1 )
throw std::runtime_error("SDL_TTF failed to initialise.");
//Load the texture
font = TTF_OpenFont( filePath.c_str(), 12 );
if(!font)
throw std::runtime_error("Couldn't load: "+ filePath);
TTF_SetFontStyle(font, TTF_STYLE_NORMAL);
surface = TTF_RenderUTF8_Blended(font, "Hello", this->textColor);
Uint8 colors = surface->format->BytesPerPixel;
int texture_format;
if (colors == 4) { // alpha
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
} else { // no alpha
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, colors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels);
SDL_FreeSurface(surface);
GLfloat vertices[] = {
//X Y Z R G B A U V
-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.f, 1.f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.f, 1.f,
-1.0f, -0.4f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.f, 0.f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.f, 1.f,
1.0f, -0.4f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 1.f, 0.f,
-1.0f, -0.4f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.f, 0.f
};
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(program->attrib("vert"));
glVertexAttribPointer(program->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 9*sizeof(GLfloat), NULL);
glEnableVertexAttribArray(program->attrib("color"));
glVertexAttribPointer(program->attrib("color"), 4, GL_FLOAT, GL_TRUE, 9*sizeof(GLfloat), (const GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(program->attrib("texcoord"));
glVertexAttribPointer(program->attrib("texcoord"), 2, GL_FLOAT, GL_TRUE, 9*sizeof(GLfloat), (const GLvoid*)(7 * sizeof(GLfloat)));
我已经按照下面的评论附上了我用于顶点属性的代码。
编辑:在一条已被删除的回复中,有人询问 SDL_TTF 是否返回 3 或 4 个 channel 。它正在返回 BGRA 图像。我试过将片段着色器更改为
#version 330
in vec2 texCoord;
in vec4 fragColor;
out vec4 finalColor;
uniform sampler2D myTextureSampler;
void main() {
finalColor = texture( myTextureSampler, texCoord ).rgba;
}
注意 vec4,并使用 rgba 而不是 rgb。这只会导致一个黑色矩形。我还尝试使用 SDL_LoadBMP() 生成一个表面,它给出了完全相同的结果。
最佳答案
你的来电
glTexImage2D(GL_TEXTURE_2D, 0, colors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels);
是个问题。
第三个参数错误:
http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml
Specifies the number of color components in the texture.
Must be one of base internal formats given in Table 1,
one of the sized internal formats given in Table 2, or one
of the compressed internal formats given in Table 3, below.
我怀疑你希望你的是 GL_RGBA(或者你希望 opengl 以什么格式存储你的纹理)
我现在才看到,但是您在片段着色器中只使用了 3 个 channel 。 Blended 函数要求您使用 4 个 channel ,否则 alpha channel 会被弄乱。
我认为您的“主要”问题出在其他地方,因为那应该只会使整个表面的颜色保持不变。 (不是你看到的“垃圾”)
我很快编写了这个程序,主要完成您的工作。我认为它比我的存储库更能帮助您,因为它直截了当。
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <SDL2/SDL_ttf.h>
#include <string>
#include <iostream>
using namespace std;
SDL_Window *window = NULL;
SDL_GLContext context = NULL;
TTF_Font* font = NULL;
SDL_Surface* surface = NULL;
//OpenGL Objects
GLuint vao;
GLuint vbo;
GLuint texture;
//Shader Objects
GLuint program;
GLuint vs;
GLuint fs;
//Sampler Object
GLuint uniformSampler;
//Callback Function
APIENTRY GLvoid debugMessageCallbackFunction( GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar* message, GLvoid* userParam)
{
cerr << endl << "\t" << message << endl;
}
//The shaders are identical to yours
const string fragmentShaderString =
"#version 130\n" // My laptop can't do OpenGL 3.3 so 3.0 will have to do
"in vec2 texCoord;\n"
"in vec4 fragColor;\n"
"\n"
"out vec4 finalColor;\n"
"\n"
"uniform sampler2D myTextureSampler;\n"
"void main() {\n"
" finalColor = texture( myTextureSampler, texCoord ) * fragColor;\n"
"}";
const string vertexShaderString =
"#version 130\n"
"\n"
"in vec3 vert;\n"
"in vec4 color;\n"
"in vec2 texcoord;\n"
"\n"
"out vec4 fragColor;\n"
"out vec2 texCoord;\n"
"void main() {\n"
" fragColor = color;\n"
" gl_Position = vec4(vert, 1);\n"
" texCoord = texcoord;\n"
"}\n";
//Your vertices, but I changed alpha to 1.0f
const GLfloat vertices[] =
{
//X Y Z R G B A U V
-1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.f, 1.f,
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.f, 1.f,
-1.0f, -0.4f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.f, 0.f,
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.f, 1.f,
1.0f, -0.4f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.f, 0.f,
-1.0f, -0.4f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.f, 0.f
};
int main(int argc, char* args[])
{
//Create Window and Context
window = SDL_CreateWindow("SDL Text with OpenGL", 0, 0, 640, 480, SDL_WINDOW_OPENGL);
//Set Core Context
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
context = SDL_GL_CreateContext(window);
//Simple OpenGL State Settings
glViewport( 0.f, 0.f, 640.f, 480.f);
glClearColor( 0.f, 0.f, 0.f, 1.f);
//Init Glew
//Set glewExperimental for Core Context
glewExperimental=true;
glewInit();
//Set Blending
//Required so that the alpha channels show up from the surface
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Simple callback function for GL errors
glDebugMessageCallbackARB(debugMessageCallbackFunction, NULL);
//Create Shaders
vs = glCreateShader(GL_VERTEX_SHADER);
fs = glCreateShader(GL_FRAGMENT_SHADER);
//Source Pointers
const GLchar* vsSource= &vertexShaderString[0];
const GLchar* fsSource = &fragmentShaderString[0];
//Set Source
glShaderSource(vs, 1, &vsSource, NULL);
glShaderSource(fs, 1, &fsSource, NULL);
//Compile Shaders
glCompileShader(fs);
glCompileShader(vs);
//Create Shader Program
program = glCreateProgram();
//Attach Shaders to Program
glAttachShader(program, vs);
glAttachShader(program, fs);
//No need for shaders anymore
glDeleteShader(vs);
glDeleteShader(fs);
//Set Attribute Locations
glBindAttribLocation(program, 0, "vert");
glBindAttribLocation(program, 1, "color");
glBindAttribLocation(program, 2, "texcoord");
//Link Program
glLinkProgram(program);
//Setup VAO and VBO
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 9 * 6, vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), NULL);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat),(GLvoid*)(3*sizeof(GLfloat)));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat),(GLvoid*)(7*sizeof(GLfloat)));
//Init TTF
TTF_Init();
//Open Font
font = TTF_OpenFont("DroidSansFallbackFull.ttf", 30);
SDL_Color color = {255, 255, 255, 255};
//Create Surface
surface = TTF_RenderUTF8_Blended(font, "This is TEXT!", color);
//Your format checker
GLenum format = (surface->format->BytesPerPixel==3)?GL_RGB:GL_RGBA;
//Create OpenGL Texture
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D( GL_TEXTURE_2D, 0, format, surface->w, surface->h, 0,
format, GL_UNSIGNED_BYTE, surface->pixels);
//Set Some basic parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Set up Sampler
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
uniformSampler = glGetUniformLocation(program, "myTextureSampler");
//It defaults to using GL_TEXTURE0, so it's not necessary to set it
//in this program it's generally a good idea.
//--------------------------------------------------------------------------------------
// DRAW STAGE
//--------------------------------------------------------------------------------------
glUseProgram(program);
//glBindVertexArray(vao); - still in use
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
SDL_GL_SwapWindow(window);
//Sleep for 2s before closing
SDL_Delay(2000);
}
我没有进行任何错误检查或关闭任何资源,因为它只是作为引用而不是为了使用。
平时我不使用glew,但是编写代码来手动获取这样一个小程序的功能似乎毫无意义。
它编译为
g++ source.cpp -g -lSDL2 -lSDL2_ttf -lGL -GLEW -o demo
在 Linux 上。您可能需要针对 Windows 进行一些调整( header 文件可能会略有变化,库也会发生变化),我认为它可以在 Mac 上正常运行。
编辑 2:
要在 Windows 上使用 mingw 编译它,您需要将 APIENTRY 添加到回调函数,并且 main 应该有参数。更改代码以反射(reflect)这一点。
经过测试,它可以在 windows 和 linux 上运行。 (前提是您的实现可以访问 GL_ARB_debug_callback 扩展,如果不只是将其注释掉的话)
关于c++ - SDL_TTF 绘制垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19748147/
我在通过 SDL_ttf 在 OpenGL 中显示文本时遇到问题。我编写了 LoadFont() 函数,它加载字体并制作 OpenGL 纹理。 int LoadFont( char *name, GL
如何在代码块中设置 sdl_ttf?我已经阅读了lazyfoo关于向sdl添加新库的教程,并已成功向其中添加了sdl_image。然而,ttf 拒绝工作。我已经下载了文件,将头文件放入 sdl 文件夹
我发布了我认为相关的部分代码。我正在尝试通过 SDL_TTF 为我的菜单绘制一些文本。每次单击按钮时,我都会从服务器获取一串字符。类似于“I1P1I2P1I3P1I4P1I5P1I6P1I7P1I8P
我是编程初学者,我在使用 SDL_TTF 调用的函数时遇到了麻烦: SDL_Surface *TTF_RenderText_Solid(TTF_Font *字体,const char *text,SD
我正在尝试使用 OpenGL 和 SDL,使用 SDL_ttf 将文本渲染到纹理,但代码渲染垃圾。 我的“渲染到纹理代码”: GLuint textToTexture(std::string & te
我遇到了 SDL_ttf 的问题,无论我用 TTF_RenderText_Solid 函数做什么,它都拒绝呈现任何文本。我的源代码在这个问题中有点重(大约 150 行之类)所以我将它们的链接放在 Pa
我正在使用 SDL_ttf,但在 mingw32 中,我下载所有内容并尝试以下程序 #include #include "SDL_ttf.h" #include using namespace s
我使用 SDL 进行开发已有一段时间了,但我认为我需要另一个挑战。所以我决定使用 SDL_TTF 在屏幕上绘制一些文本。 我尝试在 0,0 处渲染文本,但它有点低于屏幕边框。所以这意味着它没有在 0,
我正在尝试用 C++ 制作一个 openGL 游戏,并且我正在尝试实现一个文本系统,为此,我正在尝试使用 SDL_ttf。 我已经在另一个项目中使用了 SDL_ttf,但使用了另一个 api,所以我编
我正在使用 codeblocks 并且我已经安装了 librares 并且那里没有错误...当我构建项目时,编译器说它没有错误,当我运行它时,它只是弹出一个窗口,里面只有黑色,它应该会出现“Hola
所以,我正在开发一个命令提示符游戏,现在我从小处着手。我已经掌握了打印速度较慢的文本系统的基础知识,但我遇到了一个我不确定如何解决的问题。 基本上;文本会拉伸(stretch)以适合预定义的框: 预定
有没有办法在 SDL_TFF 中使用默认系统字体,而无需编写特定于平台的代码?目前我只使用 GNU FreeFont's 之一, 但我希望能够使用默认的系统字体。 最佳答案 那么,什么是“默认系统字体
当一串文本的长度超过 300 时,我希望它换行并继续。我读到这就是您的做法,但它不起作用 - 它只是延长了文本。 如何实现? const char* message = "example text t
前几天我问了一个问题,关于使用 SDL 渲染 TTF 字体,并被指向 SDL_TTFL 我已经尝试使用 SDL_TTF 库,但我得到的只是屏幕上的垃圾 我已经包含了我的着色器,这对于这个程序来说非常简
在我的游戏中,当“时间”处于事件状态时,它总是会在 5 个“小时”后崩溃。当它运行时,它工作正常,直到它开始显示不正确的时间(原因不明)并且它会在 5 个“小时”后由于段错误而崩溃。这很奇怪,因为以前
在病毒迫使我重置为出厂状态后,我一直试图在我的计算机上设置 SDL。让 SDL 在我的 IDE CodeBlocks 上运行很容易,但设置扩展库就没那么容易了。 CodeBlocks 识别库的存在,但
我是 OpenGL 的初学者,我创建了一个使用 SDL_TTF 在 OpenGL 中写入文本的函数。这是我的函数的代码: #define WINDOW_WIDTH 832 #define WINDOW
我一直在研究 SDL 和 OpenGL(在 C++ 中),并决定在我的游戏中添加一些文本。 我已经学习了一些教程,但我总是得到同样的错误:“找不到 .ttf”我确定之前有人问过它,但是你应该把字体放在
这是一个例子: 下面是相应的代码: TTF_Font *Sans = TTF_OpenFont("resources/fonts/lato/Lato-Semibold.ttf", 36); i
我有C语言代码,可以使用Linux中的SDL_ttf库在屏幕上显示文本。 TTF_Font *font; font = TTF_OpenFont("FreeSans.ttf", 20);
我是一名优秀的程序员,十分优秀!