我已经实现了一个系统,从理论上讲,它可以遍历活动实体的列表,并绘制与每个实体相关联的着色器(假设它有一个)。然而,无论我尝试了什么,都没有显示在屏幕上。
我已经确认每个组件都被正确地创建/加载,并且数据确实在那里,我不仅仅是指向空。
这是我的Sprite渲染系统(还没有实现纹理)和:
# include "../ECS.h"
# define XTILES 64
# define YTILES 36
void renderSprites(ECS* ecs, int width, int height) {
if (!ecs)
return;
for (Entity entity = 0; entity < (ecs -> entities -> count); entity++) {
if (isLiving(ecs, entity)) {
Shader* shader = (Shader*) getComponent(ecs, entity, SHADER);
Texture* texture = (Texture*) getComponent(ecs, entity, TEXTURE);
Transform* transform = (Transform*) getComponent(ecs, entity, TRANSFORM);
if (!shader || !transform)
continue;
if (!(shader -> generated)) {
glGenVertexArrays(1, &(shader -> VAO));
glGenBuffers(1, &(shader -> VBO));
glGenBuffers(1, &(shader -> EBO));
glBindVertexArray(shader -> VAO);
shader -> generated = 1;
}
// Make it changeable for textures
float vertices[] = {
(((transform -> position)[0] + 0.5f) / (XTILES / 2)), (((transform -> position)[1] + 0.5f) / (YTILES / 2)), 0.0f, 1.0f, 0.0f, 0.0f,
(((transform -> position)[0] + 0.5f) / (XTILES / 2)), (((transform -> position)[1] - 0.5f) / (YTILES / 2)), 0.0f, 1.0f, 1.0f, 0.0f,
(((transform -> position)[0] - 0.5f) / (XTILES / 2)), (((transform -> position)[1] - 0.5f) / (YTILES / 2)), 0.0f, 0.0f, 1.0f, 0.0f,
(((transform -> position)[0] - 0.5f) / (XTILES / 2)), (((transform -> position)[1] + 0.5f) / (YTILES / 2)), 0.0f, 0.0f, 0.0f, 1.0f,
};
unsigned int indices[] = {
0, 1, 3,
1, 2, 3
};
glBindBuffer(GL_ARRAY_BUFFER, shader -> VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shader -> EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*) 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*) (3 * sizeof(float)));
glEnableVertexAttribArray(1);
if (texture)
glBindTexture(GL_TEXTURE_2D, texture -> data);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader -> data);
glBindVertexArray(shader -> VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
}
}
我如何调用主循环中的方法:
//...
last = time();
while (!app.quit) {
resetInput();
now = time();
delta = now - last;
if (delta > (1000 / app.fps)) {
last = now;
inputProc(&app);
frame();
renderSprites(app.ecs, app.width, app.height);
SDL_GL_SwapWindow(app -> window);
SDL_Delay(1);
}
}
//...
我试图仅使用我的着色器代码创建一个最小的可重复使用的示例,但我创建的示例代码实际上起作用了,并在屏幕上呈现了一个正方形:
# define WIDTH 600
# define HEIGHT 600
# define XTILES 24
# define YTILES 24
# define GLEW_STATIC
# define NO_SDL_GLEXT
# include <GL/glew.h>
# include <SDL2/SDL.h>
# include <SDL2/SDL_opengl.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# define BUFFSIZE 1024
# define MAXSIZE 1048576
typedef struct Shader {
int generated;
unsigned int data;
unsigned int VBO, VAO, EBO;
} Shader;
char* loadshader(char*);
Shader* createShader(char* vertexfile, char* fragmentfile) {
const char* vertexcode = loadshader(vertexfile);
unsigned int vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vertexcode, NULL);
glCompileShader(vertex);
{
char log[1024]; int success; glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex, 1024, NULL, log);
printf("Vertex Shader Failed to Compile!n> OpenGL Error: %sn", log);
}
}
const char* fragmentcode = loadshader(fragmentfile);
unsigned int fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fragmentcode, NULL);
glCompileShader(fragment);
{
char log[1024]; int success; glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment, 1024, NULL, log);
printf("Fragment Shader Failed to Compile!n> OpenGL Error: %sn", log);
}
}
unsigned int data = glCreateProgram();
glAttachShader(data, vertex);
glAttachShader(data, fragment);
glLinkProgram(data);
{
char log[1024]; int success; glGetProgramiv(data, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(data, 1024, NULL, log);
printf("Shader Failed to Link!n> OpenGL Error: %s", log);
}
}
glDeleteShader(vertex);
glDeleteShader(fragment);
free((void*) vertexcode);
free((void*) fragmentcode);
Shader* shader = (Shader*) malloc(sizeof(Shader));
shader -> data = data;
shader -> generated = 0;
return shader;
}
void renderSprite(SDL_Window*, Shader*, float*);
int WinMain(int argc, char const *argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("Basic Window", 960, 170, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(window);
glewInit();
Shader* shader = createShader("data/02.vs", "data/02.fs");
float position[] = {0.0f, 0.0f};
renderSprite(window, shader, position);
SDL_Delay(2500);
position[0] = 0.75f + (XTILES / 3); position[1] = 0.75f + (YTILES / 3);
renderSprite(window, shader, position);
SDL_Delay(1250);
position[0] = 0.75f + (XTILES / 3); position[1] = -0.75f - (YTILES / 3);
renderSprite(window, shader, position);
SDL_Delay(1250);
position[0] = -0.75f - (XTILES / 3); position[1] = -0.75f - (YTILES / 3);
renderSprite(window, shader, position);
SDL_Delay(1250);
position[0] = -0.75f - (XTILES / 3); position[1] = 0.75f + (YTILES / 3);
renderSprite(window, shader, position);
SDL_Delay(1250);
position[0] = 0.0f; position[1] = 0.0f;
renderSprite(window, shader, position);
SDL_Delay(2500);
return 0;
}
void renderSprite(SDL_Window* window, Shader* shader, float position[2]) {
if (!shader)
return;
if (!(shader -> generated)) {
printf("%sn", "Generating Shader Buffers");
glGenVertexArrays(1, &(shader -> VAO));
glGenBuffers(1, &(shader -> VBO));
glGenBuffers(1, &(shader -> EBO));
glBindVertexArray(shader -> VAO);
shader -> generated = 1;
}
float vertices[] = {
((position[0] + 0.5f) / (XTILES / 2)), ((position[1] + 0.5f) / (YTILES / 2)), 0.0f, 1.0f, 0.0f, 0.0f,
((position[0] + 0.5f) / (XTILES / 2)), ((position[1] - 0.5f) / (YTILES / 2)), 0.0f, 1.0f, 1.0f, 0.0f,
((position[0] - 0.5f) / (XTILES / 2)), ((position[1] - 0.5f) / (YTILES / 2)), 0.0f, 0.0f, 1.0f, 0.0f,
((position[0] - 0.5f) / (XTILES / 2)), ((position[1] + 0.5f) / (YTILES / 2)), 0.0f, 0.0f, 0.0f, 1.0f,
};
unsigned int indices[] = {
0, 1, 3,
1, 2, 3
};
glBindBuffer(GL_ARRAY_BUFFER, shader -> VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shader -> EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*) 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*) (3 * sizeof(float)));
glEnableVertexAttribArray(1);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader -> data);
glBindVertexArray(shader -> VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
SDL_GL_SwapWindow(window);
SDL_Delay(1);
}
char* loadshader(char* filename) {
FILE* file = fopen(filename, "r");
if (!file)
return NULL;
int flag = 0;
char* shader = (char*) malloc(MAXSIZE);
char* buffer = (char*) malloc(BUFFSIZE);
while (fgets(buffer, BUFFSIZE, file) != NULL)
strcat(shader, buffer);
free(buffer);
fclose(file);
return shader;
}
解决方案:显然,错误不在我的渲染代码中,而在我的着色器中。我已经更改了顶点和碎片着色器中变量的名称,OpenGL不喜欢这样。在我将其改回默认名称后,一切都开始正常工作。
1条答案
按热度按时间zmeyuzjn1#
解决方案:显然,错误不在我的渲染代码中,而在我的着色器中。我已经更改了顶点和碎片着色器中变量的名称,OpenGL不喜欢这样。在我将其改回默认名称后,一切都开始正常工作。