#include <GLFW/glfw3.h>
#include <GLES2/gl2.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
// Vertex Shader source code
const char* vertexShaderSource = R"(
#version 330 core
layout(location = 0) in vec3 inPosition; // Vertex positions
layout(location = 1) in vec3 inColor; // Vertex colors
out vec3 fragColor; // Output color to the fragment shader
void main()
{
gl_Position = vec4(inPosition, 1.0);
fragColor = inColor; // Pass color to the fragment shader
}
)";
// Fragment Shader source code
const char* fragmentShaderSource = R"(
#version 330 core
in vec3 fragColor; // Input color from the vertex shader
out vec4 outColor; // Output color
void main()
{
outColor = vec4(fragColor, 1.0); // Set the fragment color using the input color
}
)";
void sleep_for_microseconds(unsigned int microseconds) {
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = microseconds * 1000;
nanosleep(&ts, NULL);
}
GLfloat vertices[9];
GLfloat colors[9];
void renderloop(GLuint vao, GLuint vbo, GLuint colorBuffer)
{
define_vertices();
define_colors();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Update the VBO with new vertex data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW);
//glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// Render loop
// Clear the screen
glClearColor(0.35f, 0.15f, 0.25f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw the triangle
glDrawArrays(GL_TRIANGLES, 0, 3*100);
glFinish();
}
void render()
{
static int framecount = 0;
printf("%d framecount\n", framecount);
GLuint vao;
GLuint vbo;
GLuint colorBuffer;
if (framecount == 0)
{
// Compile and link shaders
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);
// Use the shader program for rendering
glUseProgram(shaderProgram);
// Vertex array object
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Vertex buffer object
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Vertex attribute pointers (positions)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// Vertex attribute pointers (colors)
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0); // Vertex attribute location 0 (positions)
glEnableVertexAttribArray(1); // Vertex attribute location 1 (colors)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW);
}
framecount+=1;
renderloop(vao,vbo,colorBuffer);
framecount++;
}
float randomFloat(float min, float max) {
return min + ((float)rand() / RAND_MAX) * (max - min);
}
// Main function
void main(void) {
// Initialize GLFW
glfwInit();
define_vertices();
define_colors();
// Create a window
GLFWwindow *window = glfwCreateWindow(640, 480, "OpenGL Triangle", NULL, NULL);
if (window == NULL) {
glfwTerminate();
return;
}
// Make the window the current context
glfwMakeContextCurrent(window);
for(int i=0;i<10000;i++)
{
render();
glfwSwapBuffers(window);
glfwPollEvents();
sleep_for_microseconds(40000);
}
// Terminate GLFW
glfwTerminate();
}
define_colors和define_vertices是两个函数,它们在每帧之后更新颜色和顶点全局变量。我已经验证了一帧的代码并且工作正常(当存在顶点和颜色的静态数组时)。但是,当我拥有如下所示的颜色和顶点的动态变量时,不会渲染任何三角形。这里可能有什么问题。我通过在生成的顶点中添加打印来验证,它似乎生成正确。
我将您的代码移植到 Visual Studio 2019 并进行了一些修改,使其绘制一个颜色不断变化的简单旋转三角形。编译器抱怨局部变量 vao、vbo 和 colorBuffer 在未初始化的情况下使用。您应该立即初始化(在第 0 帧)并在下一帧中使用。所以你不应该为此使用局部变量。要么将它们移出函数作用域(例如全局变量),要么将它们设置为静态变量,例如:
void render()
{
static GLuint vao;
static GLuint vbo;
static GLuint colorBuffer;
static int framecount = 0;
printf("%d framecount\n", framecount);
if (framecount == 0)
{
// Compile and link shaders
...
}
framecount += 1;
renderloop(vao, vbo, colorBuffer);
framecount++;
}
在这些更新之后,我可以毫无问题地渲染我的旋转三角形。