有人能给我解释一下,我如何在OpenGL中渲染多个不同纹理的物体吗?
我认为我接近最终结果,但目前我被困在这里,我不知道下一步需要做什么。真的需要一些帮助!
目前,这就是我所拥有的:
> < li>
drawSphere():根据经度和纬度的数量绘制UV球体
int numberOfVerices = 0;
for(int i = 0; i <= lats; i++) {
double lat0 = M_PI * (-0.5 + (double) (i - 1) / lats);
double z0 = sin(lat0);
double zr0 = cos(lat0);
double lat1 = M_PI * (-0.5 + (double) i / lats);
double z1 = sin(lat1);
double zr1 = cos(lat1);
for(int j = 0; j <= longs; j++) {
double lng = 2 * M_PI * (double) (j - 1) / longs;
double x = cos(lng);
double y = sin(lng);
glNormal3f(x * zr0, y * zr0, z0);
vertices.push_back(x * zr0);
vertices.push_back(y * zr0);
vertices.push_back(z0);
indices.push_back(numberOfVerices);
numberOfVerices++;
vertices.push_back(x * zr1);
vertices.push_back(y * zr1);
vertices.push_back(z1);
indices.push_back(numberOfVerices);
numberOfVerices++;
}
indices.push_back(GL_PRIMITIVE_RESTART_FIXED_INDEX);
}
SetupGeometry():该方法用于绑定顶点和纹理坐标。
DrawSphere(300,300);
glGenBuffers(1, &vboVertex);
glBindBuffer(GL_ARRAY_BUFFER, vboVertex);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glGenBuffers(1, &vboTexture);
glBindBuffer(GL_ARRAY_BUFFER, vboTexture);
glBufferData(GL_ARRAY_BUFFER, texture.size() * sizeof(GLfloat), &texture[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glGenBuffers(1, &vboIndex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndex);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
numsToDraw = indices.size();
nums = indices.size();
char text[1000];int长度;
vertexSource = filetobuf("space/sphere.vert");
fragmentSource = filetobuf("space/sphere.frag");
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertexShader, 1, (const GLchar**) &vertexSource, 0);
glShaderSource(fragmentShader, 1, (const GLchar**) &fragmentSource, 0);
fprintf(stderr, "Compiling vertex shader....\n");
glCompileShader(vertexShader);
fprintf(stderr, "Compiling fragment shader....\n");
glCompileShader(fragmentShader);
fprintf(stderr, "Done....\n");
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindAttribLocation(shaderProgram, 0, "in_Position");
glBindAttribLocation(shaderProgram, 1, "Texture_Coord");
printf("Linking program ... \n");
glLinkProgram(shaderProgram);
glGetProgramInfoLog(shaderProgram, 1000, &length, text);
if(length > 0){
fprintf(stderr, "Validate Shader Program\n%s\n", text );
}
glUseProgram(shaderProgram);
GLuint纹理[2];glGenTextures(2,纹理);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
data = stbi_load(fileName, &w, &h, &n, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glUniform1i(glGetUniformLocation(shaderProgram, "texture_Sun"), 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
stbi_image_free(data);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture[1]);
data = stbi_load(fileName1, &w, &h, &n, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glUniform1i(glGetUniformLocation(shaderProgram, "texture_Earth"), 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
stbi_image_free(data);
glClearColor(0.0,0.0、0.0和1.0);/*使我们的背景为黑色*/glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(GL_PRIMITIVE_RESTART_FIXED_INDEX);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndex);
glPushMatrix();
glLoadIdentity();
glm::mat4 Projection = glm::perspective(50.0f, 5.0f / 3.0f, 1.0f, 100.0f);
glm::mat4 View = glm::lookAt(
glm::vec3(0, 5, 2),
glm::vec3(0, 0, 0),
glm::vec3(0, 1, 0)
);
/* Animations */
GLfloat angle = (GLfloat) (i);
View = glm::translate(View, glm::vec3(2.0f, 0.0f, 0.0f));
View = glm::rotate(View, angle * 0.5f, glm::vec3(0.0f, 0.0f, 1.0f));
/* ******* */
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 MVP = Projection * View * Model;
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "mvpMatrix"), 1, GL_FALSE, glm::value_ptr(MVP));
glDrawElements(GL_QUAD_STRIP, numsToDraw, GL_UNSIGNED_INT, NULL);
glPopMatrix();
glPushMatrix();
glLoadIdentity();
glm::mat4 Projection1 = glm::perspective(50.0f, 5.0f / 3.0f, 1.0f, 100.0f);
glm::mat4 View1 = glm::lookAt(
glm::vec3(0, 5, 2),
glm::vec3(0, 0, 0),
glm::vec3(0, 1, 0)
);
/* Animations */
GLfloat angle1 = (GLfloat) (i);
View1 = glm::translate(View1, glm::vec3(-2.0f, 0.0f, 0.0f));
View1 = glm::rotate(View1, angle1 * -0.5f, glm::vec3(0.0f, 0.0f, 1.0f));
/* ******* */
glm::mat4 Model1 = glm::mat4(1.0f);
MVP = Projection1 * View1 * Model1;
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "mvpMatrix"), 1, GL_FALSE, glm::value_ptr(MVP));
glDrawElements(GL_QUAD_STRIP, nums, GL_UNSIGNED_INT, NULL);
glPopMatrix();
VertexShader:
#version 330 core
precision highp float;
attribute vec3 in_Position;
attribute vec3 in_Position1;
varying vec4 Texture_Coord;
uniform mat4 mvpMatrix;
void main(void){
gl_Position = mvpMatrix * vec4(in_Position, 1.0);
Texture_Coord = vec4(in_Position, 1.0);
}
碎片遮光器:
#version 330 core
precision highp float;
varying vec4 Texture_Coord;
uniform sampler2D texture_Sun;
uniform sampler2D texture_Earth;
out vec4 FragColor;
void main(void){
vec2 longLat = vec2((atan(Texture_Coord.y, Texture_Coord.x)/3.1415926 + 1) * 0.5, (asin(Texture_Coord.z) / 3.1415926 + 0.5));
FragColor = texture2D(texture_Sun, longLat);
FragColor = texture2D(texture_Earth, longLat);
}
主要代码:
SetupGeomtry();
SetupShader();
SetupTexture("images/Earth.jpg", "images/sun.jpg");
/*
* Main loop
*/
int i = 0;
while(!glfwWindowShouldClose(window)){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Render(i+=1);
glfwSwapBuffers(window);
glfwPollEvents();
Sleep(10);
}
通常您会加载纹理(即将它们缓冲到GPU):
GLuint texture[2];
glGenTextures(2, texture);
glBindTexture(GL_TEXTURE_2D, texture[0]);
data = stbi_load(fileName, &w, &h, &n, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
stbi_image_free(data);
glBindTexture(GL_TEXTURE_2D, texture[1]);
data = stbi_load(fileName1, &w, &h, &n, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
stbi_image_free(data);
然后在绘制每个对象之前绑定所述对象的相关纹理:
// already selected the shader programme for both Sun and Earth
GLint textureLocation = glGetUniformLocation(shaderProgram, "texture_CelestialBody");
// optionally remember more locations for multi texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glUniform1i(textureLocation, 0);
// optionally bind more textures for multi texture shader...
// draw Sun now
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glUniform1i(textureLocation, 0);
// optionally bind more textures for multi texture shader...
// draw Earth now
然后<code>texture_CelestialBody</code>识别太阳和地球的纹理-即碎片着色器不会区分这两个。
我正在制作一个对象加载器,所有的纹理部分都在不同的纹理文件中。将其映射到模型上的最佳解决方案是什么?我是否需要将每个具有自己纹理的零件视为一个模型,以便最终实体具有多个单独的绘图调用,每个调用具有一个纹理?
我创建了一个类来保存我的模型信息。我必须正确渲染模型并正确包装纹理,但是由于某种原因,如果我有多个模型,它会将我所有的模型纹理化为仅1个纹理,正如您在这张图片中看到的:http://imgur.com/d0glIwF 知道为什么会这样吗? 这是我的代码: 提前谢谢你。
译注 注意,由于作者对教程做出了更新,之前本节使用的是SOIL库,但现在改为了使用stb_image.h库,关于SOIL配置的部分现在已经被修改,但我仍决定将这部分教程保留起来,放到一个历史存档中,如果有需要的话可以到这里来查看。 我们已经了解到,我们可以为每个顶点添加颜色来增加图形的细节,从而创建出有趣的图像。但是,如果想让图形看起来更真实,我们就必须有足够多的顶点,从而指定足够多的颜色。这将会
将图片加载后创建纹理对象,纹理将直接用于绘制 createTextures(object) 纹理异步加载,批量异步加载接口 手Q版本:7.8.0 函数参数object属性: 属性名 类型 是否必填 说明 file Array 是 要加载的图片文件数组 success Function 否 接口调用成功回调 fail Function 否 接口调用失败回调 complete Function 否 接
假设我有一个金字塔…我知道如何绘制它,我知道如何为整个金字塔设置纹理,但如何为每面墙设置不同的纹理? 我通过在 我试图通过添加<code>GL11.glBindTexture(GL11.GL_TEXTURE_2D,TEXTURE.getTextureID())来绑定纹理 后,但
我正在用OpenGL3.3开发一个3D程序。到目前为止,我设法渲染了许多立方体和一些球体。我需要纹理所有的立方体的脸与一个共同的纹理,除了一个脸应该有一个不同的纹理。我尝试了一个单一的纹理,一切都很好,但当我试图添加另一个纹理时,程序的行为似乎是随机的。 我的问题: 有没有一种合适的方式将多个纹理传递给着色器? 我应该如何跟踪人脸以呈现正确的纹理? 搜索我发现两次定义顶点可能很有用,但我不知道为什