使用OpenGL核心配置文件,我正在尝试创建一个填充屏幕的纹理,并在纹理中间显示一个白色方块。
#include <SDL2/SDL.h>
#include "glad/glad.h"
#define SIMPLE_VERTEX_SHADER "#version 330 core \n \
layout (location = 0) in vec3 aPos; \n \
layout (location = 1) in vec2 aTexCoord; \n \
out vec2 TexCoord; \n \
void main() { \n \
gl_Position = vec4(aPos, 1.0f); \n \
TexCoord = vec2(aTexCoord.x, aTexCoord.y); \n \
}\n\0"
#define SIMPLE_FRAGMENT_SHADER "#version 330 core \n \
out vec4 FragColor; \n \
in vec3 ourColor; \n \
in vec2 TexCoord; \n \
uniform sampler2D tex; \n \
void main() { \n \
FragColor = texture(tex, TexCoord); \n \
}\n\0"
int main(int argv, char** args) {
SDL_Window *window;
SDL_GLContext glcontext;
if (SDL_Init(SDL_INIT_VIDEO)) {
printf("Unable to initialise SDL: %s\n", SDL_GetError());
SDL_Quit();
exit(1);
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
int screen_width, screen_height;
screen_height = screen_width = 500;
window = SDL_CreateWindow("Texture Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if (!window) {
printf("Unable to create window: %s\n", SDL_GetError());
SDL_Quit();
exit(1);
}
glcontext = SDL_GL_CreateContext(window);
SDL_GL_SetSwapInterval(1);
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
{
printf("Failed to initialize GLAD\n");
}
const GLchar* vertexShaderSource = SIMPLE_VERTEX_SHADER;
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n%s\n", infoLog);
}
const GLchar* fragmentShaderSource = SIMPLE_FRAGMENT_SHADER;
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n%s\n", infoLog);
}
GLuint shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
printf("ERROR::SHADER::PROGRAM::LINKING_FAILED\n%s\n", infoLog);
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GLfloat vertices[] = {
1.0f, 1.0f, 0.0f, 1.0, 0.0f,
1.0f, -1.0f, 0.0f, 1.0, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0, 0.0f
};
GLfloat indices[] = {
0, 1, 3,
1, 2, 3
};
bool running;
running = true;
GLuint VAO, VBO, EBO;
SDL_Surface* surface;
SDL_Event e;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
GLuint texture;
glGenTextures(1, &texture);
surface = SDL_CreateRGBSurface(0, screen_width, screen_height, 32, 0, 0, 0, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
while(running) {
while(SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
running = false;
}
if (e.type == SDL_KEYDOWN)
{
switch (e.key.keysym.sym)
{
case SDLK_ESCAPE:
running = false;
break;
default:
break;
}
}
}
if (SDL_MUSTLOCK(surface)) {
SDL_LockSurface(surface);
}
uint8_t* pixel_data = (uint8_t*)surface->pixels;
for (int y = screen_height * 0.25; y < screen_height * 0.75; ++y) {
for (int x = screen_width * 0.25; x < screen_width * 0.75; ++x) {
pixel_data[4 * (y * surface -> w + x) + 0] = 0xFF;
pixel_data[4 * (y * surface -> w + x) + 1] = 0xFF;
pixel_data[4 * (y * surface -> w + x) + 2] = 0xFF;
pixel_data[4 * (y * surface -> w + x) + 3] = 0xFF;
}
}
if (SDL_MUSTLOCK(surface)) {
SDL_UnlockSurface(surface);
}
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glUseProgram(0);
SDL_GL_SwapWindow(window) ;
}
SDL_GL_DeleteContext(glcontext);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
打开时显示白色屏幕(好像我将清晰颜色设置为白色),然后几乎立即变为黑屏,然后保持这样。
我显然做错了什么,但我无法解决问题。我觉得我的着色器是问题所在。但我不确定。
是否有人能够指出我做错了什么?
感谢。
答案 0 :(得分:0)
我在评论中添加了一个基于keltar答案的答案,将这个问题从未答复的标签中删除。如果凯尔塔答案我将删除我的答案。
问题是顶点属性在行中被限定为浮点数:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
但是纹理期望无符号字节:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
因此,更改顶点属性可以解决问题。
答案 1 :(得分:0)
指数定义为
GLfloat indices[] = {
0, 1, 3,
1, 2, 3
};
但是,索引必须是整数。后来在绘图时,据说索引是GLuint:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
并且浮点位被解释为uint,给出无效值,如1065353216,1077936128,...,这大大超过顶点缓冲区大小。
将索引定义为GLuint(或uint32_t)。