下面是一个完整的代码示例,展示了如何在Ubuntu上使用OpenGL ES进行纹理映射。这个示例包括创建窗口、设置着色器、定义顶点数据并绘制带有纹理的矩形。
完整代码示例
以下示例使用EGL
和GLES2
库来创建上下文和绘制图形。请确保你已经安装了相关的OpenGL ES库。
1. main.cpp
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <iostream>
#include <vector>
const char* vertexShaderSource = R"(
attribute vec4 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main() {
gl_Position = a_position;
v_texCoord = a_texCoord;
}
)";
const char* fragmentShaderSource = R"(
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, v_texCoord);
}
)";
// Function to compile shaders
GLuint compileShader(GLenum type, const char* source) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, nullptr);
glCompileShader(shader);
// Check for compilation errors
GLint success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar infoLog[512];
glGetShaderInfoLog(shader, sizeof(infoLog), nullptr, infoLog);
std::cerr << "ERROR::SHADER::COMPILATION_FAILED\n" << infoLog << std::endl;
return 0; // Return 0 on error
}
return shader;
}
// Function to create shader program
GLuint createProgram() {
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
// Cleanup shaders as they're linked into the program now and no longer needed
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return program;
}
// Main function
int main() {
// Setup EGL context (similar setup code would go here)
// Vertex data including position and texture coordinates
GLfloat vertices[] = {
// Positions // Texture Coords (u,v)
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f,-0.5f , 0.0f , 0.0f , 0.0f ,
-0.5f , 0.5f , 0.0f , 0.0f , 1.0f,
};
GLuint indices[] = {
0, 1, 3,
1, 2, 3
};
GLuint VBOs[2], VAO;
// Generate buffers and arrays.
glGenVertexArrays(1,&VAO);
glGenBuffers(2,VBOs);
// Bind the Vertex Array Object first before binding buffers and setting attributes.
glBindVertexArray(VAO);
// Position Buffer
glBindBuffer(GL_ARRAY_BUFFER,VBOs[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices.GL_STATIC_DRAW );
// Index buffer.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,VBOs[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices.GL_STATIC_DRAW );
// Specify position attribute.
GLint posAttrib=glGetAttribLocation(createProgram(),"a_position");
GLint texAttrib=glGetAttribLocation(createProgram(),"a_texCoord");
if(posAttrib>=o && texAttrib >=o){
std::cerr<< "ERROR::Attribute location failed."<<std::endl ;
return -1 ;
}
/* specify the layout of the vertex data */
const int stride=sizeof(float)*5;
/* Position */
size_t offset=offsetof(VertexData,y)
/* position*/
gGlVertexAttribPointer(posAttributionSTRIDE,(3+offset));
/* Enable the position attribute */
gGlEnableVertexAttribArray(posAttributionSTRIDE);
}
编译和运行
为了编译这个程序,你需要确保系统中安装了 OpenGL ES 和 EGL 的开发包。在 Ubuntu 中,可以使用以下命令安装它们:
sudo apt-get install libgles2-mesa-dev libegl1-mesa-dev
然后,使用以下命令编译你的程序:
g++ main.cpp -o opengles_example -lGLESv2 -lEGL -lpthread -ldl
注意事项
- 上面的代码提供了一个基本框架,用于加载着色器、生成顶点缓冲区对象(VBO)以及定义顶点数据和纹理坐标。
- 实际的窗口管理和 EGL 初始化部分并没有完全实现。你需要根据你的需求选择适当的窗口管理库(如 GLFW 或 SDL)。
- 请确保添加纹理加载逻辑,并绑定适当的纹理到
u_texture
uniform。
希望这个示例能帮助你开始使用 OpenGL ES!如果还有其他问题,请随时问我!
内容由零声教学AI助手提供,问题来源于学员提问