Reputation: 57
first let's look at my code for playercar Render:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->texture2DObj);
glUniform1i(1, 0);
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
glEnableVertexAttribArray(0);
int offset = 0;
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, this->vertexBufferSize,(const void *)offset);//???????????
offset += 3 * sizeof(GLfloat);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, this->vertexBufferSize, (const void*)offset);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
glDrawElements(GL_TRIANGLES, this->indexBufferSize, GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
and another texture i want to load in program name oppCar_1:
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, this->textureObj);
glUniform1i(1, 1);
int offset = 0;
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBufferOppCar_1);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, this->vertexBufferSizeOppCar_1, (const void *)offset);
glEnableVertexAttribArray(1);
offset += 3 * sizeof(GLfloat);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, this->vertexBufferSizeOppCar_1, (const void *)offset);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBufferOppCar_1);
glDrawElements(GL_TRIANGLES, this->indexBufferSizeOppCar_1, GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
and this is my Render function:
glUseProgram(ShaderProgram::ProgramObject);
glClearColor(0.0, 0.0, 0.0, 1.0);
score++;
glClear(GL_COLOR_BUFFER_BIT);
//oppcar_1.SetPosition(posCar);
playercar.Render();
oppcar_1.Render();
but it shows only one texture at time! when i change glActiveTexture(GL_TEXTURE0) in player car to any number more than 0 it changes to next texture that it's for oppCar,so as i see the textures are loaded perfectly but not showing two texture at time,so what's the problem? and another question is is we need one program to create,link,and use for every texture that we need or not? if you need more detail please tell me.
Upvotes: 0
Views: 47
Reputation: 3577
sorry I do not understand why and to whom you pass the uniform "glUniform1i(1, 0);". Uniforms are for shaders and therefore you should assign uniforms after you call the glUseProgram(ShaderProgram::ProgramObject);
More than that, it looks wrong the way you proceed.
My advice is to work on a single texture unit at the moment (you are not doing really a multitexture, you have a single texture per object).
In other words, do not change the uniform glUniform1i(1, 1); glUniform1i(1, 0); but always refer to the texture unit 0.
Another point, how can you be sure that the uniform 1 is the ID of the sampler2D of your fragment shader?
The best approach would be to get the ID of the uniform just after you compiled and linked the vertex+fragment shader. This is the way to go. The ID of the uniforms are managed by the driver and you cannot be assured that the ID is 0 or 1 or 2 etc.
This is the reason why there is the function glGetUniformLocation in Opengl. Use it, it is much safer and correct.
For the time being, an alternative solution is to activate only the texture unit 0 glActiveTexture(GL_TEXTURE0); and to use the sample2D 0 in your shader. The performance penality should not represent a problem in your current setup.
I hope this helps. Maurizio
Upvotes: 0