【发布时间】:2019-01-26 03:15:19
【问题描述】:
在我之前的问题 here 使用 OpenGL 和 Obj-C 交换图像之后,我决定也使用带有着色器和纹理的 C++ 使用 original tutorial。我想要做的是切换不同的纹理。这是我的[更新]代码
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "SOIL2/SOIL2.h"
#include "Shader.h"
using namespace std;
//window
const GLuint WIDTH = 750, HEIGHT = 750;
int main( )
{
glfwInit( );
//GLFW
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE ); //only for mac
glfwWindowHint( GLFW_RESIZABLE, GL_FALSE );
GLFWwindow *window = glfwCreateWindow( WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr );
int screenWidth, screenHeight;
glfwGetFramebufferSize( window, &screenWidth, &screenHeight );
if ( nullptr == window )
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate( );
return EXIT_FAILURE;
}
glfwMakeContextCurrent( window );
//ModernOpenGL
glewExperimental = GL_TRUE;
if ( GLEW_OK != glewInit( ) )
{
cout << "Failed to initialize GLEW" << endl;
return EXIT_FAILURE;
}
//viewport
glViewport( 0, 0, screenWidth, screenHeight );
//enable alpha
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
//shaders
Shader ourShader( "resources/shaders/core.vs", "resources/shaders/core.frag" );
//vertices
GLfloat vertices[] =
{
//position //color //texture Coords
1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right
1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left
-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left
};
GLuint indices[] =
{
0, 1, 3, // 1st triangle
1, 2, 3 // 2nd triangle
};
GLuint VBO, VAO, EBO;
glGenVertexArrays( 1, &VAO );
glGenBuffers( 1, &VBO );
glGenBuffers( 1, &EBO );
glBindVertexArray( VAO );
glBindBuffer( GL_ARRAY_BUFFER, VBO );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, EBO );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW );
//position
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ), ( GLvoid * ) 0 );
glEnableVertexAttribArray(0);
//color
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ), ( GLvoid * )( 3 * sizeof( GLfloat )));
glEnableVertexAttribArray(1);
//texture Coord
glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ), ( GLvoid * )( 6 * sizeof( GLfloat )));
glEnableVertexAttribArray( 2 );
glBindVertexArray( 0 ); // unbind VAO
//CREATE TEXTURE
GLuint textures[2];
glGenTextures(2, textures);
int width, height;
unsigned char * image;
//texture1
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
image = SOIL_load_image("resources/res/images/green.png", &width, &height, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
// glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
//texture2
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
image = SOIL_load_image("resources/res/images/img1.png", &width, &height, 0, SOIL_LOAD_RGBA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
//parameters
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
//filtering
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glGenerateMipmap( GL_TEXTURE_2D );
//loop
while ( !glfwWindowShouldClose( window ) )
{
glfwPollEvents( );
//render
glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );
//draw triangle
//if
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0);
//draw container
glBindVertexArray( VAO );
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0 );
glBindVertexArray( 0 );
glfwSwapBuffers( window );
}
//de-alocated stuff
glDeleteVertexArrays( 1, &VAO );
glDeleteBuffers( 1, &VBO );
glDeleteBuffers( 1, &EBO );
glfwTerminate( );
return EXIT_SUCCESS;
}
这是纹理碎片
#version 330 core
in vec3 ourColor;
in vec2 TexCoord;
out vec4 color;
uniform sampler2D ourTexture1;
uniform sampler2D ourTexture2;
uniform int usetexture = 0;
void main()
{
if (usetexture == 0)
color = texture(ourTexture1, TexCoord);
if (usetexture == 1)
color = texture(ourTexture1, TexCoord);
}
如何正确调用它们并让它们切换?甚至一种纹理都没有显示。我想从 SOIL 加载图像在 img1 和 img2 之间进行更改。但是一直卡住。有什么建议吗?
【问题讨论】:
-
在 c++ 代码中,您将两个纹理绑定在同一个绑定点
0,而在着色器中,您在两种情况下都使用ourTexture1。 -
@t.niese 我已经更新了我的代码。
-
你必须为第一个纹理设置
glActiveTexture(GL_TEXTURE0);,为第二个纹理设置glActiveTexture(GL_TEXTURE1);。清除游戏循环中每一帧开始时的颜色和深度缓冲区 -glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); -
@Rabbid76 我相信我已经设置了 glActiveTexture(GL_TEXTURE0);两种质地。我已经听从了你对 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 的建议。 ,还是不行。
-
对于
usetexture == 0和usetexture == 1,您仍然使用texture(ourTexture1, TexCoord)。你为什么要一遍又一遍地将glBindTexture(GL_TEXTURE_2D, textures[0])绑定到0?