下面是一个在 Ubuntu 上使用 OpenGL ES 实现一个矩形的完整代码示例,包括顶点着色器、片段着色器,以及 C++ 代码来创建和渲染这个矩形。该示例将演示如何使用 v_texCoord
在 Shader 中赋值。
1. 顶点着色器 (Vertex Shader)
#version 300 es
layout(location = 0) in vec4 a_position; // 顶点位置
layout(location = 1) in vec2 a_texCoord; // 输入的纹理坐标
out vec2 v_texCoord; // 向片段着色器传递的纹理坐标
void main() {
gl_Position = a_position; // 设置顶点的位置
v_texCoord = a_texCoord; // 将输入的纹理坐标赋值给输出变量
}
2. 片段着色器 (Fragment Shader)
#version 300 es
precision mediump float;
in vec2 v_texCoord; // 从顶点着色器接收的纹理坐标
out vec4 fragColor; // 输出颜色
uniform sampler2D u_texture; // 输入的纹理
void main() {
fragColor = texture(u_texture, v_texCoord); // 根据纹理坐标获取颜色值
}
3. C++ 主程序实现
以下是一个简单的 OpenGL ES 应用程序,在窗口中绘制一个带有纹理的矩形。
#include <GLES3/gl3.h>
#include <EGL/egl.h>
#include <GLFW/glfw3.h>
#include <iostream>
// Vertex data for a rectangle (two triangles)
GLfloat vertices[] = {
// Position // Texture coordinates
-0.5f, -0.5f, 0.0f, 0.0f, // Bottom-left corner
0.5f, -0.5f, 1.0f, 0.0f, // Bottom-right corner
-0.5f, 0.5f, 0.0f, 1.0f, // Top-left corner
0.5f, -0.5f, 1.0f, 0.0f, // Bottom-right corner
0.5f, 0.5f, 1.0f, 1.0f, // Top-right corner
-0.5f, 0.5f, 0.0f, 1.0f // Top-left corner
};
// Load shader from source code and compile it.
GLuint loadShader(GLenum type, const char *shaderSrc) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &shaderSrc, nullptr);
glCompileShader(shader);
GLint success;
glGetShaderiv(shader, GL_COMPILE_STATUS,&success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(shader,sizeof(infoLog),nullptr ,infoLog);
std::cerr << "ERROR::SHADER::COMPILATION_FAILED\n" << infoLog << std::endl;
return -1;
}
return shader;
}
int main() {
glfwInit();
#ifdef __APPLE__
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR ,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR ,2);
#else
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR ,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR ,3);
#endif
GLFWwindow* window = glfwCreateWindow(800 ,600 ,"OpenGL ES Rectangle" ,NULL ,NULL);
if(!window) {
std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Vertex Array Object and Vertex Buffer Object setup.
GLuint VAO ,VBO;
glGenVertexArrays(1,&VAO);
glGenBuffers(1,&VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices ,GL_STATIC_DRAW);
// Define the vertex attributes.
glVertexAttribPointer(0 ,2 ,GL_FLOAT ,GL_FALSE ,4 * sizeof(GLfloat),(void*)nullptr); // Position attribute layout(location=0)
glEnableVertexAttribArray(0);
glVertexAttribPointer(1 ,2 ,GL_FLOAT ,GL_FALSE ,4 * sizeof(GLfloat),(void*)(2 * sizeof(GLfloat))); // Texture coordinate attribute layout(location=1)
glEnableVertexAttribArray(1);
const char *vertexShaderSrc = /* Your vertex shader code */;
const char *fragmentShaderSrc = /* Your fragment shader code */;
GLuint vertexShader = loadShader(GL_VERTEX_SHADER,vertexShaderSrc );
GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER,fragmentShaderSrc );
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram,vertexShader );
glAttachShader(shaderProgram,fragmentShader );
glLinkProgram(shaderProgram );
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram );
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES,offsetof(Vertex)*6 ,6 );
glfwSwapBuffers(window );
glfwPollEvents();
}
// Cleanup resources.
glDeleteVertexArrays(1,&VAO );
glDeleteBuffers(1,&VBO );
glDeleteProgram(shaderProgram );
free(vertex_shader_src );
free(fragment_shader_src );
glfwTerminate();
return EXIT_SUCCESS ;
}
注意事项:
- 在实际开发中,请确保链接适当的库,并进行错误处理。
- 示例中的 Shader 源代码(
vertex_shader_src
和fragment_shader_src
)需要替换为上面提供的 GLSL 着色器代码。 - 确保正确安装了 OpenGL ES 开发环境,并按照项目需要设置编译选项。
这个例子展示了如何使用 OpenGL ES 渲染一个简单矩形,并使用 v_texCoord
来处理贴图。如果你有其他问题或需要更多帮助,请告诉我!
内容由零声教学AI助手提供,问题来源于学员提问